|  | dirs = {
  "up-left": "Northwest",
  "up": "North",
  "up-right": "Northeast",
  "left": "West",
  "right": "East",
  "down-left": "Southwest",
  "down": "South",
  "down-right": "Southeast",
  "ascend": "Up",
  "descend": "Down"
}
function initWorld(state) {
  initRoomState(state);
}
function initRoomState(state) {
  state.player.rooms = {};
  Object.entries(world).forEach(([key, val]) => {
    state.player.rooms[key] = {};
  });
}
function showActionDescription(desc) {
  const descHolder = document.querySelector("#desc");
  descHolder.textContent = desc;
}
function removeActionDescription() {
  const descHolder = document.querySelector("#desc");
  descHolder.textContent = "";
}
function moveToRoom(dest, state) {
  const room = world[dest];
  console.log(room);
  if (room.hooks) {
    for (let hook of room.hooks) {
      if (!hook(room, state)) {
        return;
      }
    }
  }
  updateRoom(dest, state);
}
function updateRoom(dest, state) {
  const room = world[dest];
  if (!state.player.rooms[dest.id]) {
    state.player.rooms[dest.id] = {};
  }
  const areaName = document.querySelector("#area-name");
  const areaDesc = document.querySelector("#area-desc");
  areaName.textContent = room.name;
  areaDesc.textContent = room.desc;
  const moveHolder = document.querySelector("#move-holder");
  moveHolder.innerHTML = "";
  Object.entries(dirs).forEach(([dir, name]) => {
    const button = document.createElement("button");
    button.classList.add("move-button")
    button.id = "move-" + dir;
    button.classList.add("disabled");
    button.setAttribute("disabled", "true");
    button.textContent = dirs[dir];
    moveHolder.appendChild(button);
  });
  if (room.exits) {
    Object.entries(room.exits).forEach(([dir, exit]) => {
      const button = document.querySelector("#move-" + dir);
      const dest = world[exit.target];
      // don't even show an exit if this fails!
      if (exit.show) {
        if (!exit.show.every(cond => cond(room, state))) {
          return;
        }
      }
      button.textContent = dest.name;
      // if any condition fails, don't enable/add a listener
      if (exit.conditions) {
        if (!exit.conditions.every(cond => cond(room,state))) {
          return;
        }
      }
      button.classList.remove("disabled");
      button.removeAttribute("disabled");
      button.addEventListener("click", () => {
        // todo: log
        moveToRoom(exit.target, state);
      })
    });
  }
  const actionHolder = document.querySelector("#actions");
  actionHolder.innerHTML = "";
  if (room.actions) {
    room.actions.forEach(action => {
      const button = document.createElement("button");
      button.classList.add("action-button");
      if (action.show) {
        if (!action.show.every(cond => cond(room, state))) {
          return;
        }
      }
      button.textContent = action.name;
      actionHolder.appendChild(button);
      if (action.conditions) {
        if (!action.conditions.every(cond => cond(room, state))) {
          button.classList.add("disabled");
          button.setAttribute("disabled", "true");
          return;
        }
      }
      button.addEventListener("click", () => {
        action.execute(room, state);
        updateRoom(room.id, state);
      });
      button.addEventListener("mouseenter", () => {
        showActionDescription(action.desc);
      });
      button.addEventListener("mouseleave", () => {
        removeActionDescription();
      });
    });
  }
}
world = {
  "Home": {
    "id": "Home",
    "name": "Home",
    "desc": "Where the wifi autoconnects",
    "actions": [
      {
        "name": "Squint",
        "desc": "Squint in a very aggressive manner",
        "execute": (self, state) => {
          state.player.rooms[self.id].squinted = true;
          print(["You stare at the wall and notice a secret door. But where is the key?"]);
        }
      },
      {
        "name": "Find Keys",
        "desc": "Find your keys",
        "execute": (self, state) => {
          state.player.items.keys.push("Locked Room");
          print(["You found your keys under the couch cushions"]);
        },
        "show": [
          (self, state) => {
            return state.player.rooms[self.id].squinted;
          },
          (self, state) => {
            return !state.player.items.keys.includes("Locked Room");
          }
        ]
      }
    ],
    "exits": {
      "up": {
        "target": "Locked Room",
        "desc": "It's locked!",
        "move": "You enter the secret locked room",
        "conditions": [
          (self, state) => {
            return state.player.items.keys.includes("Locked Room");
          }
        ],
        "show": [
          (self, state) => {
            console.log(self);
            return state.player.rooms[self.id].squinted;
          }
        ]
      }
    },
    "hooks": [
      (self, state) => {
        print(["This is a test of the hooks"]);
        return true;
      }
    ]
  },
  "Locked Room": {
    "id": "Locked Room",
    "name": "Locked Room",
    "desc": "Super seecret",
    "exits": {
      "down": {
        "target": "Home",
        "desc": "Back to home",
        "move": "You dab"
      }
    }
  }
}
 |