Tetgame mark
Tetgame deep-code room

The Diamond Mine

Inspect Tetgame Rabbot behavior files and prepare the future safe editor for strategy tuning.

Welcome guest — sign in through the Trigame front door when you are ready.
Log in via Trigame

Diamond Mine

The Tetgame answer to the Gold Room.

Read-only starter

The Diamond Mine is intended to expose the deeper machinery of Tetgame Rabbots: behavior files, scoring nudges, strategy filters, voice loaders, backups, and eventually safe editing tools.

Current pass: this page only lists and displays local Tetgame JS/JSON files from js/rabbots, js/personalities, and js/voices. It does not save changes yet.

Behavior / voice file viewer

js/personalities/glacier_borealis.js

/*
 * Tetgame Rabbot: Glacier Borealis
 *
 * Glacier v7 — human-hint counter-swim. Tetgame supplies legal moves in
 * ctx.tokenMoves and ctx.tetMoves; this file only chooses among those legal moves.
 *
 * v7 notes:
 * - Takes the hint from the two human wins against Hamilton.
 * - When Hamilton opens 1:10, Glacier now swims through B first, anchors
 *   1:1, then after Hamilton's 1:2 / 1:3 bite she looks for the human
 *   follow-up: 1:0, then 2:3.
 * - When Glacier opens 1:10 and Hamilton answers 1:1 + [C], she no longer
 *   settles for the tying 1:2 / 1:9 pair.  She counter-expands from tet 2
 *   through B when legal, then anchors the new tet at 3:10.
 *
 * v6 notes:
 * - v5 restored parity, but Glacier still took a denying root token before
 *   placing the tet.  That denial worked, but it was not yet a shared-corner
 *   advantage.
 * - v6 adds a narrow tet-first rule: when Hamilton has only one root token and
 *   Glacier has a legal swim, she places the tet first, then anchors a root
 *   corner on the newly shared/common corner.
 * - This is deliberately small: no new broad scoring analysis, just an
 *   objective move-order correction around the first response pattern.
 * - v2 over-clamped. Against Hamilton it placed two root tokens before swimming,
 *   which locked the board and left Glacier inside the shark mouth.
 * - v5 keeps objective socket maps, but also an objective rule for timing:
 *   one root bite, then swim. Do not double-token the root while a tet expansion
 *   is still legal.
 * - When Glacier starts and Hamilton answers with the center-mouth bite, she
 *   now uses a named counter-pair instead of the bad 8/4 drift: first 1:2,
 *   then 1:9 when legal.
 * - When Hamilton starts, Glacier answers 1:1, then expands from face 2/C if
 *   she can, so the fight moves into water instead of sealing into a tiny loss.
 *
 * Voice lines live separately in js/voices/glacier_borealis.json.
 */
(function(global){
  'use strict';

  const registry = global.TetgameRabbotBrains = global.TetgameRabbotBrains || {};

  function cloneMove(move, fallbackReason){
    if (!move) return null;
    const copy = Object.assign({}, move);
    if (!copy.reason && fallbackReason) copy.reason = fallbackReason;
    return copy;
  }

  function moveAt(list, index){
    return Array.isArray(list) && list.length > index ? list[index] : null;
  }

  function pass(reason){
    return {type:'pass', score:-1, reason:reason || 'no legal action found'};
  }

  function scoreOf(move){
    return Number(move && move.score || 0);
  }

  function canOpen(ctx){
    return ctx && Number(ctx.tetCount || 0) <= 0;
  }

  function activeCount(ctx){
    return Math.max(2, Number(ctx && ctx.activeCount || 2));
  }

  function openingLimit(ctx, extra){
    const active = activeCount(ctx);
    return Math.max(2, Math.min(5, active + Number(extra || 1)));
  }

  function moveTetId(move){
    return Number(move && move.socket && move.socket.metadata ? move.socket.metadata.tetId : -1);
  }

  function socketIndex(move){
    return Number(move && move.socket && move.socket.metadata ? move.socket.metadata.socketIndex : -1);
  }

  function isCornerSocket(idx){
    return idx >= 0 && idx <= 3;
  }

  function isEdgeMidSocket(idx){
    return idx >= 4 && idx <= 9;
  }

  function isCenterSocket(idx){
    return idx === 10;
  }

  function newestTokenTetId(ctx){
    const moves = Array.isArray(ctx && ctx.tokenMoves) ? ctx.tokenMoves : [];
    let newest = Math.max(1, Number(ctx && ctx.tetCount || 1));
    moves.forEach(move => {
      const id = moveTetId(move);
      if (id > newest) newest = id;
    });
    return newest;
  }

  function exactSocketMove(moves, tetId, socketOrder, minRawScore, reasonPrefix){
    if (!Array.isArray(moves) || tetId < 1) return null;
    const bySocket = Object.create(null);

    moves.forEach(move => {
      if (moveTetId(move) !== tetId) return;
      const idx = socketIndex(move);
      if (idx < 0) return;
      if (!bySocket[idx] || scoreOf(move) > scoreOf(bySocket[idx])) bySocket[idx] = move;
    });

    for (let i = 0; i < socketOrder.length; i++) {
      const idx = socketOrder[i];
      const move = bySocket[idx];
      if (!move) continue;
      if (typeof minRawScore === 'number' && scoreOf(move) < minRawScore) continue;
      return cloneMove(move, reasonPrefix + ' socket ' + tetId + ':' + idx);
    }

    return null;
  }

  function tetFaceIndex(move){
    return Number(move && move.face && move.face.metadata ? move.face.metadata.faceIndex : -1);
  }

  function tetFaceTetId(move){
    return Number(move && move.face && move.face.metadata ? move.face.metadata.tetId : -1);
  }

  function exactTetFaceMove(moves, sourceTetId, faceOrder, reasonPrefix){
    if (!Array.isArray(moves) || !moves.length) return null;
    const byFace = Object.create(null);

    moves.forEach(move => {
      const faceIdx = tetFaceIndex(move);
      if (faceIdx < 0) return;
      const faceTet = tetFaceTetId(move);
      if (sourceTetId >= 1 && faceTet >= 1 && faceTet !== sourceTetId) return;
      if (!byFace[faceIdx] || scoreOf(move) > scoreOf(byFace[faceIdx])) byFace[faceIdx] = move;
    });

    for (let i = 0; i < faceOrder.length; i++) {
      const faceIdx = faceOrder[i];
      const move = byFace[faceIdx];
      if (move) return cloneMove(move, reasonPrefix + ' face ' + sourceTetId + ':' + faceIdx);
    }

    // Some engine builds may not expose face tet ids.  Fall back to face order
    // only, so the brain still works on older tetgame files.
    for (let i = 0; i < faceOrder.length; i++) {
      const faceIdx = faceOrder[i];
      const move = moves.find(m => tetFaceIndex(m) === faceIdx);
      if (move) return cloneMove(move, reasonPrefix + ' face ' + sourceTetId + ':' + faceIdx);
    }

    return null;
  }

  // Exact socket maps.
  // Socket 10 is the center.  Sockets 0-3 are corners.  Sockets 4-9 are edge midpoints.
  // Glacier's first job is to own one root anchor, swim, then use named counters.  v2's double-corner clamp locked her in place.
  const ROOT_FIRST_CENTER   = [10, 1, 3, 0, 2, 8, 6, 4, 5, 7, 9];
  const ROOT_ICE_ANCHOR     = [1, 3, 0, 2, 10, 8, 6, 4, 5, 7, 9];
  const ROOT_MOUTH_DENIAL   = [2, 0, 3, 1, 9, 6, 5, 8, 7, 4, 10];
  const ROOT_EDGE_FREEZE    = [9, 6, 5, 8, 7, 4, 2, 0, 3, 1, 10];
  const ROOT_STARTER_COUNTER = [2, 0, 3, 1, 10, 9, 6, 5, 8, 7, 4];
  const ROOT_SECOND_COUNTER  = [9, 6, 5, 8, 7, 4, 2, 0, 3, 1, 10];
  const ROOT_ESCAPE_COUNTER  = [0, 2, 3, 1, 6, 5, 9, 8, 7, 4, 10];

  // v6: after swimming first, do not drift to an edge midpoint.  Take a root
  // corner so the token denies Hamilton while also sitting on the shared face.
  const ROOT_SHARED_CORNER_AFTER_SWIM = [1, 3, 0, 2, 10, 6, 5, 9, 8, 7, 4];

  // v5: restore the v3 outer-current order.  The attempted v4 breakaway
  // grabbed 1:7/1:4 and 2:6/2:9 too early, which let Hamilton take the
  // stronger reply pairs.  Glacier should regain the tying structure first.
  const OUTER_GLACIER_SWIM  = [10, 1, 3, 0, 2, 8, 6, 4, 5, 7, 9];
  const FACE_COLD_WATER     = [2, 0, 1, 3];

  // v7 human-hint maps.  The two human wins against Hamilton showed two
  // objective recipes:
  // 1) If Hamilton opens 1:10, swim B first, then play 1:1; after the lock,
  //    play 1:0 and 2:3 to make the new tet score for Glacier.
  // 2) If Glacier opens 1:10 and Hamilton replies 1:1 + [C], counter-swim
  //    from tet 2 through B, then claim the new tet center at 3:10.
  const FACE_HUMAN_OPEN_WATER = [1, 2, 0, 3];
  const HUMAN_ROOT_AFTER_LOCK = [0, 2, 3, 1, 10, 6, 5, 9, 8, 7, 4];
  const HUMAN_SECOND_TET_BITE = [3, 10, 6, 8, 9, 0, 1, 2, 4, 5, 7];
  const HUMAN_NEW_TET_ANCHOR  = [10, 3, 0, 2, 1, 6, 8, 9, 5, 4, 7];
  const FACE_COUNTER_FROM_C   = [1, 0, 2, 3];

  function bestShapedToken(moves){
    if (!Array.isArray(moves) || !moves.length) return null;

    let best = moves[0];
    let bestValue = -999999;

    moves.forEach((move, i) => {
      const idx = socketIndex(move);
      const id = moveTetId(move);
      let value = scoreOf(move);

      // Glacier is supposed to out-think, not just race.  Corners and centers
      // are stable swimming markers; raw edge-midpoints are accepted when they
      // are already productive, but not as cheap early bait.
      if (isCenterSocket(idx)) value += 1.45;
      if (isCornerSocket(idx)) value += 1.25;
      if (isEdgeMidSocket(idx) && value < 6) value -= 0.85;
      if (id === 1) value += 0.35;
      if (value >= 8) value += 1.50;
      if (value >= 12) value += 2.50;
      value -= i * 0.025;

      if (value > bestValue) {
        bestValue = value;
        best = move;
      }
    });

    return best;
  }

  function chooseWideIceTet(ctx){
    const moves = Array.isArray(ctx && ctx.tetMoves) ? ctx.tetMoves : [];
    if (!moves.length) return null;

    let best = moves[0];
    let bestValue = -999999;
    const lookCount = Math.min(moves.length, Math.max(4, Math.min(8, activeCount(ctx) + 4)));

    for (let i = 0; i < lookCount; i++) {
      const move = moves[i];
      if (!move) continue;
      let value = scoreOf(move);
      const faceIndex = Number(move && move.face && move.face.metadata ? move.face.metadata.faceIndex : -1);

      // Prefer clean face/corner-style swims and look a little wider than the
      // first legal placement so she is not just following Hamilton's wake.
      if (isCornerSocket(faceIndex) || isCenterSocket(faceIndex)) value += 0.65;
      if (isEdgeMidSocket(faceIndex)) value -= 1.75;
      value += i * 0.62;
      if (i >= 2) value += 0.80;
      if (i >= 5) value -= 0.20;

      if (value > bestValue) {
        bestValue = value;
        best = move;
      }
    }

    return best;
  }

  function chooseObjectiveIceToken(ctx){
    const moves = Array.isArray(ctx && ctx.tokenMoves) ? ctx.tokenMoves : [];
    if (!moves.length || activeCount(ctx) > 2) return null;

    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const boardLocked = !!(ctx && ctx.boardLocked);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;
    const newest = newestTokenTetId(ctx);

    // Empty root: take the center if available.  This is her cold-water compass.
    if (tetCount === 1 && tokenCount <= 0) {
      return exactSocketMove(
        moves,
        1,
        ROOT_FIRST_CENTER,
        -999,
        'set the polar center at'
      );
    }

    // Early duel: take only one root anchor here.  The second action should
    // usually be a tet swim if one is legal; chooseMove handles that before
    // calling this function again.
    if (tetCount === 1 && tokenCount <= 4) {
      return exactSocketMove(
        moves,
        1,
        ROOT_ICE_ANCHOR,
        -999,
        'set one ice anchor at'
      );
    }

    // Before the board branches, keep denying Hamilton's favorite one-sub mouth.
    if (tetCount === 1 && tokenCount <= 11) {
      return exactSocketMove(
        moves,
        1,
        ROOT_MOUTH_DENIAL,
        1.5,
        'freeze the root mouth at'
      );
    }

    // If Glacier started with the center and Hamilton answered with a root
    // corner plus a C-face swim, her bad v2 habit was 8 then 4.  This gives
    // Hamilton the whole mouth.  The objective counter is 1:2 first, then
    // 1:9 when the second action comes around.
    if (tetCount === 2 && tokenCount <= 5) {
      const counter = exactSocketMove(
        moves,
        1,
        firstAction ? ROOT_STARTER_COUNTER : ROOT_SECOND_COUNTER,
        -999,
        firstAction ? 'turn into the shark current at' : 'lace the undertow edge at'
      );
      if (counter) return counter;
    }

    // v5: no lead-current override here.  v4 used this slot to take
    // sockets 1:7/1:4 and 2:6/2:9 early, which handed Hamilton the stronger
    // reply sequence and produced 0-10 losses.  Fall through to the proven
    // v3 escape/current maps below.

    // Young two-tet board: protect the root before chasing the outer tet, but
    // use corners/counter-edges instead of v2's loose 8/4 drift.
    if (tetCount >= 2 && tokenCount <= 16) {
      const rootFreeze = exactSocketMove(
        moves,
        1,
        boardLocked ? ROOT_ESCAPE_COUNTER : ROOT_MOUTH_DENIAL,
        boardLocked ? 1.0 : 2.0,
        'seal the old-water counter at'
      );
      if (rootFreeze) return rootFreeze;

      const freshSwim = exactSocketMove(
        moves,
        newest,
        OUTER_GLACIER_SWIM,
        boardLocked ? 1.5 : 3.5,
        'out-swim to the cold socket at'
      );
      if (freshSwim) return freshSwim;
    }

    // Midgame: objective outer patrol, but only when the raw value is real.
    if (tetCount >= 3 && tokenCount <= 26) {
      const patrol = exactSocketMove(
        moves,
        newest,
        OUTER_GLACIER_SWIM,
        4.5,
        'patrol the deep ice socket at'
      );
      if (patrol) return patrol;
    }

    return null;
  }

  function chooseTetBeforeAnchor(ctx){
    const tetMoves = Array.isArray(ctx && ctx.tetMoves) ? ctx.tetMoves : [];
    if (!tetMoves.length) return null;

    const duel = activeCount(ctx) <= 2;
    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const boardLocked = !!(ctx && ctx.boardLocked);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    if (!duel || boardLocked || !firstAction) return null;

    // Hamilton's first center/root bite is better answered by swimming first.
    // The next token can then land on a shared/common corner instead of merely
    // denying from the old root before the new tet exists.
    if (tetCount === 1 && tokenCount === 1) {
      return exactTetFaceMove(
        tetMoves,
        1,
        FACE_HUMAN_OPEN_WATER,
        'take the human B-swim before the shared-corner bite through'
      ) || cloneMove(chooseWideIceTet(ctx) || tetMoves[0], 'take the human B-swim so the next bite is shared');
    }

    return null;
  }

  function chooseSharedCornerAfterSwim(ctx){
    const moves = Array.isArray(ctx && ctx.tokenMoves) ? ctx.tokenMoves : [];
    if (!moves.length || activeCount(ctx) > 2) return null;

    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    // This is the second half of the tet-first correction: after the first
    // action created a neighbor, place the denial token on a root corner before
    // the older edge-current map can pull her to 1:9 / 1:6 / 1:5 / 1:8.
    if (!firstAction && tetCount === 2 && tokenCount <= 2) {
      return exactSocketMove(
        moves,
        1,
        ROOT_SHARED_CORNER_AFTER_SWIM,
        -999,
        'pin the new shared-corner denial at'
      );
    }

    return null;
  }

  function chooseForcedEarlySwim(ctx){
    const tetMoves = Array.isArray(ctx && ctx.tetMoves) ? ctx.tetMoves : [];
    if (!tetMoves.length) return null;

    const duel = activeCount(ctx) <= 2;
    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const boardLocked = !!(ctx && ctx.boardLocked);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    if (!duel || boardLocked) return null;

    // The v2 disaster: Hamilton opens center, Glacier takes 1 and 3, and the
    // board locks into an 11-token meal.  After one root anchor, swim.
    if (!firstAction && tetCount === 1 && tokenCount >= 2 && tokenCount <= 3) {
      return exactTetFaceMove(
        tetMoves,
        1,
        FACE_HUMAN_OPEN_WATER,
        'one bite, then take the human B-swim through'
      ) || cloneMove(chooseWideIceTet(ctx) || tetMoves[0], 'one bite, then dive before the ice locks');
    }

    return null;
  }


  function chooseHumanHintCounterSwim(ctx){
    const tetMoves = Array.isArray(ctx && ctx.tetMoves) ? ctx.tetMoves : [];
    if (!tetMoves.length) return null;

    const duel = activeCount(ctx) <= 2;
    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const boardLocked = !!(ctx && ctx.boardLocked);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    if (!duel || boardLocked || !firstAction) return null;

    // Human win #1 pattern: Glacier opens 1:10, Hamilton answers 1:1 + [C].
    // Do not settle for the tying 1:2 / 1:9 center fight.  Create the third
    // tet first, then the next action can anchor 3:10.
    if (tetCount === 2 && tokenCount <= 2) {
      return exactTetFaceMove(
        tetMoves,
        newestTokenTetId(ctx),
        FACE_COUNTER_FROM_C,
        'copy the human counter-swim from Hamilton\'s C-tet through'
      ) || exactTetFaceMove(
        tetMoves,
        2,
        FACE_COUNTER_FROM_C,
        'copy the human counter-swim from tet 2 through'
      ) || cloneMove(chooseWideIceTet(ctx) || tetMoves[0], 'copy the human counter-swim before trading root tokens');
    }

    return null;
  }

  function chooseHumanHintNewTetAnchor(ctx){
    const moves = Array.isArray(ctx && ctx.tokenMoves) ? ctx.tokenMoves : [];
    if (!moves.length || activeCount(ctx) > 2) return null;

    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    // Second half of the human win #1 pattern: after the counter-swim creates
    // tet 3, anchor its center before Hamilton can make the whole match about
    // tet 1 again.
    if (!firstAction && tetCount >= 3 && tokenCount <= 3) {
      return exactSocketMove(
        moves,
        newestTokenTetId(ctx),
        HUMAN_NEW_TET_ANCHOR,
        -999,
        'anchor the human new-tet center at'
      );
    }

    return null;
  }

  function chooseHamiltonOpenFollowup(ctx){
    const moves = Array.isArray(ctx && ctx.tokenMoves) ? ctx.tokenMoves : [];
    if (!moves.length || activeCount(ctx) > 2) return null;

    const tetCount = Number(ctx && ctx.tetCount || 0);
    const tokenCount = Number(ctx && ctx.tokenCount || 0);
    const boardLocked = !!(ctx && ctx.boardLocked);
    const firstAction = Number(ctx && ctx.turnActionCount || 0) === 0;

    if (!boardLocked || tetCount !== 2 || tokenCount < 4 || tokenCount > 9) return null;

    // Human win #2 pattern after Hamilton opens 1:10 and bites 1:2 / 1:3:
    // first take 1:0, then 2:3.  This turns the denial into a scoring current
    // on the second tet instead of just a root-tet tie.
    if (firstAction) {
      return exactSocketMove(
        moves,
        1,
        HUMAN_ROOT_AFTER_LOCK,
        -999,
        'copy the human root turn at'
      );
    }

    return exactSocketMove(
      moves,
      newestTokenTetId(ctx),
      HUMAN_SECOND_TET_BITE,
      -999,
      'copy the human second-tet bite at'
    );
  }

  registry.glacier_borealis = {
    key:'glacier_borealis',
    id:'glacier_borealis',
    name:'Glacier Borealis',
    level:7,
    style:'human-hint counter-swim',
    temperament:'opens a second battlefield before fighting Hamilton on the root',

    chooseMove(ctx){
      if (!ctx || ctx.matchEnded || ctx.tournamentEnded) return null;
      if (canOpen(ctx)) return {type:'start_tet', score:1000, reason:'open the first ice shelf'};

      const token0 = moveAt(ctx.tokenMoves, 0);
      const token1 = moveAt(ctx.tokenMoves, 1);
      const tet0 = moveAt(ctx.tetMoves, 0);
      const boardLocked = !!ctx.boardLocked;
      const firstAction = Number(ctx.turnActionCount || 0) === 0;
      const tetCount = Number(ctx.tetCount || 0);
      const tokenCount = Number(ctx.tokenCount || 0);
      const duel = activeCount(ctx) <= 2;

      // v6 correction: if a token would merely deny before the swim, swim first
      // so the follow-up token can become a shared-corner denial.
      const tetBeforeAnchor = chooseTetBeforeAnchor(ctx);
      if (tetBeforeAnchor) return tetBeforeAnchor;

      // v5 keeps v3's objective swim timing before the objective token map.
      // Do not place two root tokens in a row while a tet swim is still legal.
      const forcedEarlySwim = chooseForcedEarlySwim(ctx);
      if (forcedEarlySwim) return forcedEarlySwim;

      const humanHintCounterSwim = chooseHumanHintCounterSwim(ctx);
      if (humanHintCounterSwim) return humanHintCounterSwim;

      const humanHintNewTetAnchor = chooseHumanHintNewTetAnchor(ctx);
      if (humanHintNewTetAnchor) return humanHintNewTetAnchor;

      const humanOpenFollowup = chooseHamiltonOpenFollowup(ctx);
      if (humanOpenFollowup) return humanOpenFollowup;

      const sharedCornerAfterSwim = chooseSharedCornerAfterSwim(ctx);
      if (sharedCornerAfterSwim) return sharedCornerAfterSwim;

      // Objective socket map second.  The map now names the counter-pairs rather
      // than blindly favoring loose edge-midpoints.
      const objectiveToken = chooseObjectiveIceToken(ctx);
      if (objectiveToken) return objectiveToken;

      // Only expand after the root has at least a little ice on it.  v1 often
      // expanded immediately into Hamilton's teeth; v3 anchors once, then swims.
      const swimTet = chooseWideIceTet(ctx) || tet0;
      if (!boardLocked && swimTet && firstAction && tetCount < openingLimit(ctx, duel ? 1 : 3) && tokenCount >= (duel ? 3 : 1)) {
        return cloneMove(swimTet, 'swim wider after the root is clamped');
      }

      // Fall back to shaped scoring: high raw captures still matter, but Glacier
      // keeps a preference for center/corner structure over loose edge bait.
      const shapedToken = bestShapedToken(ctx.tokenMoves) || token0;
      if (shapedToken) {
        return cloneMove(
          shapedToken,
          scoreOf(shapedToken) >= 8 ? 'freeze the richest current' : 'hold the cleanest cold point'
        );
      }

      if (!boardLocked && swimTet) return cloneMove(swimTet, 'open a colder channel');
      return cloneMove(token1, 'take the second cold line') || pass();
    }
  };
})(window);

Future safe editor shape

Borrowing the Gold Room idea without mixing Trigame and Tetgame logic.

Read original

Keep an original snapshot before the first edit.

Edit safe sections

Expose selected behavior sections without letting the page damage wrapper code.

Test in Tetgame

Save, then jump back to the Blue Room or board to test the Rabbot live.