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):
- MENU controls for Ore / Stone / Oil / Wood (enable + count) + master “Resources On”
S.resources+S.resourceSettingsgenerateResources()uses your existingRNG()(seeded) and fillsS.resourceson START GAMEdrawResources()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;
}