Title of State:

Resource Existence

Goal of Change:

Goal: resources exist, are deterministic (seeded), are visible, and are controlled by simple MENU settings.

What we will add (and only this):

  1. MENU controls for Ore / Stone / Oil / Wood (enable + count) + master “Resources On”
  2. S.resources + S.resourceSettings
  3. generateResources() uses your existing RNG() (seeded) and fills S.resources on START GAME
  4. drawResources() draws simple markers on top of the map using camX/camY (no scaling)

PATCH 1 — MENU HTML: add Resource settings block

Code to Remove

227 - 
          <div class="menuActions">
            <div class="seedRow">
              <div class="seedLabel">Seed</div>
              <input id="seedInput" class="seedInput" type="number" step="1" value="12345" />
            </div>

            <button id="btnStartGame" class="btnPrimary" type="button" disabled>START GAME</button>
          </div>

Code to Add

227 - 
          <div class="menuActions">
            <div class="seedRow">
              <div class="seedLabel">Seed</div>
              <input id="seedInput" class="seedInput" type="number" step="1" value="12345" />
            </div>

            <div class="resPanel">
              <div class="resHeader">Resources</div>

              <label class="chkRow">
                <input id="resEnable" type="checkbox" checked />
                <span>Enable Resources</span>
              </label>

              <div class="resGrid">
                <div class="resRow">
                  <label class="chkRow">
                    <input id="resOreOn" type="checkbox" checked />
                    <span>Ore</span>
                  </label>
                  <input id="resOreCount" class="countInput" type="number" step="1" min="0" value="40" />
                </div>

                <div class="resRow">
                  <label class="chkRow">
                    <input id="resStoneOn" type="checkbox" checked />
                    <span>Stone</span>
                  </label>
                  <input id="resStoneCount" class="countInput" type="number" step="1" min="0" value="35" />
                </div>

                <div class="resRow">
                  <label class="chkRow">
                    <input id="resOilOn" type="checkbox" checked />
                    <span>Oil</span>
                  </label>
                  <input id="resOilCount" class="countInput" type="number" step="1" min="0" value="12" />
                </div>

                <div class="resRow">
                  <label class="chkRow">
                    <input id="resWoodOn" type="checkbox" checked />
                    <span>Wood</span>
                  </label>
                  <input id="resWoodCount" class="countInput" type="number" step="1" min="0" value="55" />
                </div>
              </div>
            </div>

            <button id="btnStartGame" class="btnPrimary" type="button" disabled>START GAME</button>
          </div>


PATCH 2 — CSS: add Resource panel styles

Code to Remove

148 - 
  .seedInput{
    width:180px;
    padding:10px 12px;
    border-radius:10px;
    border:1px solid rgba(255,255,255,.16);
    background:rgba(0,0,0,.25);
    color:#e9f0ff;
    font-size:14px;
    outline:none;
  }

Code to Add

148 - 
  .seedInput{
    width:180px;
    padding:10px 12px;
    border-radius:10px;
    border:1px solid rgba(255,255,255,.16);
    background:rgba(0,0,0,.25);
    color:#e9f0ff;
    font-size:14px;
    outline:none;
  }

  /* Resource settings panel */
  .resPanel{
    width:100%;
    padding:12px;
    border-radius:12px;
    border:1px solid rgba(255,255,255,.14);
    background:rgba(255,255,255,.06);
  }
  .resHeader{
    font-size:13px;
    opacity:.9;
    margin-bottom:8px;
  }
  .chkRow{
    display:flex;
    align-items:center;
    gap:10px;
    font-size:13px;
    opacity:.95;
    user-select:none;
  }
  .resGrid{
    margin-top:10px;
    display:flex;
    flex-direction:column;
    gap:10px;
  }
  .resRow{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    padding:10px 10px;
    border-radius:10px;
    border:1px solid rgba(255,255,255,.10);
    background:rgba(0,0,0,.18);
  }
  .countInput{
    width:110px;
    padding:10px 10px;
    border-radius:10px;
    border:1px solid rgba(255,255,255,.16);
    background:rgba(0,0,0,.25);
    color:#e9f0ff;
    font-size:14px;
    outline:none;
    text-align:right;
  }


PATCH 3 — JS: grab resource controls

Code to Remove

348 - 
const btnBegin = document.getElementById("btnBegin");
const btnStartGame = document.getElementById("btnStartGame");
const seedInput = document.getElementById("seedInput");

Code to Add

348 - 
const btnBegin = document.getElementById("btnBegin");
const btnStartGame = document.getElementById("btnStartGame");
const seedInput = document.getElementById("seedInput");

/* Resource controls */
const resEnable   = document.getElementById("resEnable");
const resOreOn    = document.getElementById("resOreOn");
const resStoneOn  = document.getElementById("resStoneOn");
const resOilOn    = document.getElementById("resOilOn");
const resWoodOn   = document.getElementById("resWoodOn");

const resOreCount   = document.getElementById("resOreCount");
const resStoneCount = document.getElementById("resStoneCount");
const resOilCount   = document.getElementById("resOilCount");
const resWoodCount  = document.getElementById("resWoodCount");


PATCH 4 — JS: add resources + settings to State

Code to Remove

370 - 
const S = {
  paused:false,
  view:"TITLE",        // "TITLE" | "MENU" | "GAME"
  mapKey:null,         // "GRASS" | "SAND" | "SNOW"
  mouseX:0, mouseY:0,

  camX:0, camY:0,      // viewport top-left in map pixels
  keys:{},             // pressed keys map

  seed: 12345,         // deterministic seed for procedural generation

  fps:0, _acc:0, _frames:0,
  last: performance.now(),
};

Code to Add

370 - 
const S = {
  paused:false,
  view:"TITLE",        // "TITLE" | "MENU" | "GAME"
  mapKey:null,         // "GRASS" | "SAND" | "SNOW"
  mouseX:0, mouseY:0,

  camX:0, camY:0,      // viewport top-left in map pixels
  keys:{},             // pressed keys map

  seed: 12345,         // deterministic seed for procedural generation

  resourceSettings: null,
  resources: [],       // [{Type, X, Y, Radius}...]

  fps:0, _acc:0, _frames:0,
  last: performance.now(),
};


PATCH 5 — JS: add settings reader + resource generation + drawing

Code to Remove

560 - 
/* Update / Draw */

Code to Add

560 -
/* Update / Draw */

/* =========================
   SLICE A — RESOURCE EXISTENCE
   ========================= */
function readResourceSettings(){
  const on = !!resEnable.checked;

  const oreOn   = !!resOreOn.checked;
  const stoneOn = !!resStoneOn.checked;
  const oilOn   = !!resOilOn.checked;
  const woodOn  = !!resWoodOn.checked;

  const oreCount   = Math.max(0, (Number(resOreCount.value)   | 0));
  const stoneCount = Math.max(0, (Number(resStoneCount.value) | 0));
  const oilCount   = Math.max(0, (Number(resOilCount.value)   | 0));
  const woodCount  = Math.max(0, (Number(resWoodCount.value)  | 0));

  return {
    Enabled: on,
    Ore:   { Enabled: on && oreOn,   Count: oreCount },
    Stone: { Enabled: on && stoneOn, Count: stoneCount },
    Oil:   { Enabled: on && oilOn,   Count: oilCount },
    Wood:  { Enabled: on && woodOn,  Count: woodCount },
  };
}

function randRange(a,b){ return a + (b-a) * RNG(); }

function generateResources(){
  S.resources = [];
  S.resourceSettings = readResourceSettings();
  if(!S.resourceSettings.Enabled) return;

  // Keep nodes off the extreme edges a bit
  const margin = 40;
  const minX = margin, maxX = MAP_SIZE - margin;
  const minY = margin, maxY = MAP_SIZE - margin;

  const pushN = (type, n)=>{
    for(let i=0;i<n;i++){
      const node = {
        Type: type,
        X: randRange(minX, maxX),
        Y: randRange(minY, maxY),
        Radius: 16,
      };
      S.resources.push(node);
    }
  };

  if(S.resourceSettings.Ore.Enabled)   pushN("ORE",   S.resourceSettings.Ore.Count);
  if(S.resourceSettings.Stone.Enabled) pushN("STONE", S.resourceSettings.Stone.Count);
  if(S.resourceSettings.Oil.Enabled)   pushN("OIL",   S.resourceSettings.Oil.Count);
  if(S.resourceSettings.Wood.Enabled)  pushN("WOOD",  S.resourceSettings.Wood.Count);
}

function drawResources(){
  if(S.view !== "GAME") return;
  if(!S.resources || S.resources.length === 0) return;

  // draw markers in screen space using camera offset
  for(const n of S.resources){
    const sx = n.X - S.camX;
    const sy = n.Y - S.camY;

    // quick reject if far outside view
    if(sx < -40 || sy < -40 || sx > (VIEW+40) || sy > (VIEW+40)) continue;

    // marker
    ctx.globalAlpha = 0.95;

    // type styling (simple, readable)
    if(n.Type === "ORE")   ctx.fillStyle = "rgba(220,220,255,.85)";
    if(n.Type === "STONE") ctx.fillStyle = "rgba(220,220,220,.85)";
    if(n.Type === "OIL")   ctx.fillStyle = "rgba(40,40,40,.90)";
    if(n.Type === "WOOD")  ctx.fillStyle = "rgba(120,220,140,.85)";

    ctx.beginPath();
    ctx.arc(sx, sy, n.Radius, 0, Math.PI*2);
    ctx.fill();

    // label
    ctx.globalAlpha = 0.95;
    ctx.fillStyle = "rgba(0,0,0,.75)";
    ctx.font = "12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
    const letter = (n.Type === "STONE") ? "S" : n.Type[0];
    ctx.fillText(letter, sx - 4, sy + 4);
  }
  ctx.globalAlpha = 1;
}


PATCH 6 — JS: draw resources on top of the map

Code to Remove

704 - 
  // map first (so other debug overlays draw on top)
  drawMapNative();

Code to Add

704 -
  // map first (so other debug overlays draw on top)
  drawMapNative();
  // resources on top of map
  drawResources();


PATCH 7 — JS: generate resources on Start Game

Code to Remove

554 - 
btnStartGame.addEventListener("click", ()=>{
  if(!S.mapKey) return;
  reseed(seedInput.value);
  setView("GAME");
});

Code to Add

554 - 
btnStartGame.addEventListener("click", ()=>{
  if(!S.mapKey) return;
  reseed(seedInput.value);
  generateResources();
  setView("GAME");
});


PATCH 8 — HUD: show resource count

Code to Remove

742 - 
  setHUD(
  (S.paused ? "PAUSED" : "READY") +
  `\\nFPS: ${S.fps}` +
  `\\nM: ${Math.floor(S.mouseX)},${Math.floor(S.mouseY)}` +
  `\\nCAM: ${Math.floor(S.camX)},${Math.floor(S.camY)}`
);

Code to Add

742 - 
  setHUD(
  (S.paused ? "PAUSED" : "READY") +
  `\\nFPS: ${S.fps}` +
  `\\nM: ${Math.floor(S.mouseX)},${Math.floor(S.mouseY)}` +
  `\\nCAM: ${Math.floor(S.camX)},${Math.floor(S.camY)}` +
  `\\nRES: ${S.resources ? S.resources.length : 0}`
);


Patch 9 — make the MENU window box fit the new content

Code to Remove

81 - 
  .menuPanel{
    width:900px;
    height:600px;
    position:relative;
    display:flex;
    flex-direction:column;
  }

Code to Add

81 - 
  .menuPanel{
    width:980px;
    height:760px;
    position:relative;
    display:flex;
    flex-direction:column;
  }


Result