startle response

plasma-bot does 15% more damage, but costs 2 research
fault tolerance 4->5 forever drones, but costs 2 research
surfactant 2->3 foam bots, but costs 2 research
missile-bot costs 1 research
shaped charge 4->3 research cost
renormalization 40->44% chance to refund research
exciton 18->16% chance to spawn
ground state 50->40% reduced energy regen
Bayesian statistics 3.8->3% damage per research, and spawns 3 research

JUNK tech: startle response - if mobs are near boost damage, and lock mouse until you press escape
This commit is contained in:
landgreen
2022-10-27 17:31:29 -07:00
parent de6d910aca
commit f8188565a0
9 changed files with 196 additions and 83 deletions

View File

@@ -184,6 +184,7 @@
<tr> <tr>
<th>PAUSE</th> <th>PAUSE</th>
<td id='key-pause' class='key-input'>P</td> <td id='key-pause' class='key-input'>P</td>
<!-- <td class='key-used'>Escape</td> -->
<td></td> <td></td>
</tr> </tr>
<tr id="control-testing"> <tr id="control-testing">

View File

@@ -5050,7 +5050,7 @@ const b = {
y: best.y y: best.y
}; };
if (best.who.alive) { if (best.who.alive) {
const dmg = 0.65 * m.dmgScale; //********** SCALE DAMAGE HERE ********************* const dmg = 0.75 * m.dmgScale; //********** SCALE DAMAGE HERE *********************
best.who.damage(dmg); best.who.damage(dmg);
best.who.locatePlayer(); best.who.locatePlayer();
//push mobs away //push mobs away

View File

@@ -225,7 +225,68 @@ for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].link) tech.tech[i].link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(tech.tech[i].name).replace(/'/g, '%27')}&title=Special:Search' class="link">${tech.tech[i].name}</a>` if (!tech.tech[i].link) tech.tech[i].link = `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(tech.tech[i].name).replace(/'/g, '%27')}&title=Special:Search' class="link">${tech.tech[i].name}</a>`
} }
const build = { const build = {
pixelDraw() {
let count = 0
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let data = imgData.data;
function loop() {
count++
if (!(count % 2)) {
for (let y = 0; y < canvas.height; ++y) {
for (let x = 0; x < canvas.width; x += 1) {
const index = (y * canvas.width + x) * 4;
// let mag = 0;
// for (let j = 0, len = who.length; j < len; j++) {
// const dx = who[j].position.x - x;
// const dy = who[j].position.y - y;
// mag -= who[j].charge / (Math.sqrt(dx * dx + dy * dy) + 1);
// }
//get dark
// data[index + 0] *= 0.96
// data[index + 1] *= 0.96
// data[index + 2] *= 0.96
// data[index + 3] -= 1; // alpha
//invert
data[index + 0] = 255 - data[index + 0] // red
data[index + 1] = 255 - data[index + 1] // green
data[index + 2] = 255 - data[index + 2] // blue
}
}
// fade alpha for all pixels
// for (let i = 0; i < data.length; i += 4) {
// if (data[i + 3] > 0) {
// data[i + 3]--;
// }
// }
//add random speckles
// for (let i = 0, len = Math.floor(data.length / 15000); i < len; ++i) {
// const index = Math.floor((Math.random() * data.length) / 4) * 4;
// data[index + 0] = 255; // red
// data[index + 1] = 255; // green
// data[index + 2] = 255; // blue
// data[index + 3] = Math.floor(Math.random() * Math.random() * 155); // alpha
// }
// ctx.putImageData(imgData, 0, 1); //pixels fall because of the 1 in third parameter
ctx.putImageData(imgData, 0, 0);
}
if (simulation.paused && m.alive) requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
},
pauseGrid() { pauseGrid() {
// build.pixelDraw();
//used for junk estimation //used for junk estimation
let junkCount = 0 let junkCount = 0
let totalCount = 1 //start at one to avoid NaN issues let totalCount = 1 //start at one to avoid NaN issues
@@ -812,6 +873,7 @@ const input = {
event.code === input.key.left || event.code === input.key.left ||
event.code === input.key.right || event.code === input.key.right ||
event.code === input.key.pause || event.code === input.key.pause ||
// event.code === "Escape" ||
event.code === input.key.nextGun || event.code === input.key.nextGun ||
event.code === input.key.previousGun || event.code === input.key.previousGun ||
event.code === input.key.testing event.code === input.key.testing
@@ -901,6 +963,7 @@ window.addEventListener("keyup", function(event) {
}); });
window.addEventListener("keydown", function(event) { window.addEventListener("keydown", function(event) {
console.log(event.code)
switch (event.code) { switch (event.code) {
case input.key.right: case input.key.right:
case "ArrowRight": case "ArrowRight":
@@ -932,6 +995,7 @@ window.addEventListener("keydown", function(event) {
case input.key.previousGun: case input.key.previousGun:
simulation.previousGun(); simulation.previousGun();
break break
// case "Escape":
case input.key.pause: case input.key.pause:
if (!simulation.isChoosing && input.isPauseKeyReady && m.alive) { if (!simulation.isChoosing && input.isPauseKeyReady && m.alive) {
input.isPauseKeyReady = false input.isPauseKeyReady = false

View File

@@ -31,7 +31,7 @@ const level = {
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[9].ammo = 10000 // b.guns[9].ammo = 10000
// tech.giveTech("ship") // tech.giveTech("startle response")
// for (let i = 0; i < 1; ++i) tech.giveTech("junk DNA") // for (let i = 0; i < 1; ++i) tech.giveTech("junk DNA")
// tech.giveTech("dye laser") // tech.giveTech("dye laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook") // for (let i = 0; i < 1; ++i) tech.giveTech("grappling hook")
@@ -40,8 +40,6 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// canvas.requestPointerLock()
// level.testing(); // level.testing();
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500) // spawn.starter(1900, -500)
@@ -52,6 +50,7 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 }) // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech() // for (let i = 0; i < 40; ++i) tech.giveTech()
// for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); // for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech"); // for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); // for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
@@ -61,7 +60,7 @@ const level = {
// lore.techCount = 2 // lore.techCount = 2
// simulation.isCheating = false //true; // simulation.isCheating = false //true;
// level.levelsCleared = 10 // level.levelsCleared = 10
// localSettings.loreCount = 7 //this sets what conversation is heard // localSettings.loreCount = 5 //this sets what conversation is heard
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage // if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation // level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
// level.null() // level.null()

View File

@@ -232,7 +232,7 @@ const lore = {
if (input.down) { if (input.down) {
lore.miriam.text("So, No. Maybe you are lucky. Emotions are complex.") lore.miriam.text("So, No. Maybe you are lucky. Emotions are complex.")
} else if (input.up) { } else if (input.up) {
lore.anand.text("YES, Cool! I wonder if it's emotions came from watching humans. ") lore.anand.text("YES, Cool! I wonder if its emotions came from watching humans. ")
lore.sentence-- lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.miriam.text("Or maybe it learned independently, because it needed them.") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ }) lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => { lore.miriam.text("Or maybe it learned independently, because it needed them.") }) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
} else if (m.alive) { } else if (m.alive) {
@@ -246,7 +246,7 @@ const lore = {
() => { lore.anand.text("If we say the alphabet it could crouch on the correct letter to spell words.") }, () => { lore.anand.text("If we say the alphabet it could crouch on the correct letter to spell words.") },
() => { lore.miriam.text("That would take forever.") }, () => { lore.miriam.text("That would take forever.") },
() => { lore.miriam.text("I really want to know why is it generating the mobs? And why does it keep fighting them?") }, () => { lore.miriam.text("I really want to know why is it generating the mobs? And why does it keep fighting them?") },
() => { lore.anand.text("Maybe that is just part of it's expectationmaximization algorithm") }, () => { lore.anand.text("Maybe that is just part of its expectationmaximization algorithm") },
() => { lore.miriam.text("Well sure, but what does that even mean?") }, () => { lore.miriam.text("Well sure, but what does that even mean?") },
() => { () => {
lore.miriam.text("Do we all just do things because we are-") lore.miriam.text("Do we all just do things because we are-")
@@ -309,7 +309,7 @@ const lore = {
() => { setTimeout(() => { lore.miriam.text("So, you can understand us, but you may not understand everything about yourself.") }, 500); }, () => { setTimeout(() => { lore.miriam.text("So, you can understand us, but you may not understand everything about yourself.") }, 500); },
() => { setTimeout(() => { lore.anand.text("You grew from our team's project.") }, 500); }, () => { setTimeout(() => { lore.anand.text("You grew from our team's project.") }, 500); },
() => { lore.anand.text("We used a quantum computer to design an improved version of it's own architecture.") }, () => { lore.anand.text("We used a quantum computer to design an improved version of its own architecture.") },
() => { lore.anand.text("After we built the improved computer we used it to design the next iteration.") }, () => { lore.anand.text("After we built the improved computer we used it to design the next iteration.") },
() => { lore.anand.text("Your hardware is roughly the 19th generation of this process.") }, () => { lore.anand.text("Your hardware is roughly the 19th generation of this process.") },
@@ -347,7 +347,7 @@ const lore = {
() => { setTimeout(() => { lore.anand.text("WHY DID YOU SAY THAT!") }, 500) }, () => { setTimeout(() => { lore.anand.text("WHY DID YOU SAY THAT!") }, 500) },
() => { lore.miriam.text("SLIME!! Hahahahehehahaheheahae! I don't think it's gonna survive!") }, () => { lore.miriam.text("SLIME!! Hahahahehehahaheheahae! I don't think it's gonna survive!") },
() => { lore.miriam.text("I think the adversarial network doesn't like it when we decohere the quantum system in this room.") }, () => { lore.miriam.text("I think the adversarial network doesn't like it when we decohere the quantum system in this room.") },
() => { lore.anand.text("Well, that does halt it's research.") }, () => { lore.anand.text("Well, that does halt its research.") },
() => { setTimeout(() => { lore.anand.text("See you next time.") }, 1000) }, () => { setTimeout(() => { lore.anand.text("See you next time.") }, 1000) },
() => { setTimeout(() => { lore.miriam.text("Bye-bye little bot.") }, 2000) }, () => { setTimeout(() => { lore.miriam.text("Bye-bye little bot.") }, 2000) },
() => { () => {
@@ -504,8 +504,11 @@ const lore = {
() => { lore.miriam.text("Of course they attack right now.") }, () => { lore.miriam.text("Of course they attack right now.") },
() => { lore.miriam.text("Just don't get stuck in the slime.") }, () => { lore.miriam.text("Just don't get stuck in the slime.") },
() => { () => {
let count = 0
function cycle() { function cycle() {
if (mob.length === 0) { count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("I'll spawn some more power ups for you.") lore.miriam.text("I'll spawn some more power ups for you.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity); simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal") for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
@@ -523,8 +526,11 @@ const lore = {
lore.talkingColor = "#dff" lore.talkingColor = "#dff"
}, },
() => { () => {
let count = 0
function cycle() { function cycle() {
if (mob.length === 0) { count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.anand.text("DragonFlyBoss is my favorite.") lore.anand.text("DragonFlyBoss is my favorite.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity); simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal") for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
@@ -541,8 +547,11 @@ const lore = {
lore.talkingColor = "#dff" lore.talkingColor = "#dff"
}, },
() => { () => {
let count = 0
function cycle() { function cycle() {
if (mob.length === 0) { count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("Here are some extra tech.") lore.miriam.text("Here are some extra tech.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "tech")`, Infinity); simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "tech")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(0, -200 - i * 40, "tech") for (let i = 0; i < 6; i++) powerUps.spawn(0, -200 - i * 40, "tech")
@@ -561,8 +570,11 @@ const lore = {
lore.talkingColor = "#dff" lore.talkingColor = "#dff"
}, },
() => { () => {
let count = 0
function cycle() { function cycle() {
if (mob.length === 0) { count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.anand.text("I'm going to wall you in!") lore.anand.text("I'm going to wall you in!")
spawn.blockBoss(-1650, -100); spawn.blockBoss(-1650, -100);
spawn.blockBoss(1650, -100); spawn.blockBoss(1650, -100);
@@ -630,7 +642,7 @@ const lore = {
() => { lore.anand.text(`I bet the AI doesn't even know it's in space.`) }, () => { lore.anand.text(`I bet the AI doesn't even know it's in space.`) },
() => { lore.anand.text(`Well, maybe a part of it doesn't know where it is.`) }, () => { lore.anand.text(`Well, maybe a part of it doesn't know where it is.`) },
() => { lore.anand.text(`Maybe these simulations are more like a dream.`) }, () => { lore.anand.text(`Maybe these simulations are more like a dream.`) },
() => { lore.anand.text(`Although we can't assume that it's brain works like ours.`) }, () => { lore.anand.text(`Although we can't assume that its brain works like ours.`) },
() => { setTimeout(() => { lore.miriam.text("So, let's teach the AI that we are friends.") }, 500); }, () => { setTimeout(() => { lore.miriam.text("So, let's teach the AI that we are friends.") }, 500); },
() => { lore.anand.text(`How...`) }, () => { lore.anand.text(`How...`) },
() => { setTimeout(() => { lore.miriam.text("I don't know...") }, 1000); }, () => { setTimeout(() => { lore.miriam.text("I don't know...") }, 1000); },
@@ -688,11 +700,11 @@ const lore = {
}, },
() => { setTimeout(() => { lore.anand.text("haha, we did it!") }, 500); }, () => { setTimeout(() => { lore.anand.text("haha, we did it!") }, 500); },
() => { lore.miriam.text("Although, I'm not sure we should personify it with human emotions.") }, () => { lore.miriam.text("Although, I'm not sure we should personify it with human emotions.") },
() => { lore.anand.text("I agree, it's thinking may not be centered around a self or an ego.") }, () => { lore.anand.text("I agree, its thinking may not be centered around a self or an ego.") },
() => { lore.anand.text("Our brains evolved a self oriented perspective because it was a survival advantage.") }, () => { lore.anand.text("Our brains evolved a self oriented perspective because it was a survival advantage.") },
() => { lore.miriam.text("Right, and the AI's development was guided by it's own previous iterations.") }, () => { lore.miriam.text("Right, and the AI's development was guided by its own previous iterations.") },
() => { lore.miriam.text("This AI incarnation is the 18th time that it has improved on it's own hardware and software architecture.") }, () => { lore.miriam.text("This AI incarnation is the 18th time that it has improved on its own hardware and software architecture.") },
() => { lore.miriam.text("So it's internally guided evolution may not require the idea of a self.") }, () => { lore.miriam.text("So its internally guided evolution may not require the idea of a self.") },
() => { setTimeout(() => { lore.anand.text("How ever it thinks it can learn and, I think we showed it that nonviolence is an option,") }, 1000); }, () => { setTimeout(() => { lore.anand.text("How ever it thinks it can learn and, I think we showed it that nonviolence is an option,") }, 1000); },
() => { lore.anand.text("but it looks like it's still running other aggressive simulations.") }, () => { lore.anand.text("but it looks like it's still running other aggressive simulations.") },

View File

@@ -1072,7 +1072,7 @@ const m = {
if (tech.isTimeCrystals) { if (tech.isTimeCrystals) {
m.fieldRegen *= 3 m.fieldRegen *= 3
} else if (tech.isGroundState) { } else if (tech.isGroundState) {
m.fieldRegen *= 0.5 m.fieldRegen *= 0.6
} }
}, },
regenEnergy: function() { //used in drawRegenEnergy // rewritten by some tech regenEnergy: function() { //used in drawRegenEnergy // rewritten by some tech

View File

@@ -467,7 +467,7 @@ const powerUps = {
b.randomBot() b.randomBot()
if (tech.renormalization) { if (tech.renormalization) {
for (let i = 0; i < cost; i++) { for (let i = 0; i < cost; i++) {
if (Math.random() < 0.4) { if (Math.random() < 0.44) {
m.fieldCDcycle = m.cycle + 20; m.fieldCDcycle = m.cycle + 20;
powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
} }
@@ -479,7 +479,7 @@ const powerUps = {
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) { if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}` document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
} }
if (tech.renormalization && Math.random() < 0.4 && amount < 0) { if (tech.renormalization && Math.random() < 0.44 && amount < 0) {
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research"); for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
} }
if (tech.isRerollHaste) { if (tech.isRerollHaste) {
@@ -1223,7 +1223,7 @@ const powerUps = {
powerUps.spawn(x, y, "coupling"); powerUps.spawn(x, y, "coupling");
return; return;
} }
if (tech.isBoostPowerUps && Math.random() < 0.18) { if (tech.isBoostPowerUps && Math.random() < 0.16) {
powerUps.spawn(x, y, "boost"); powerUps.spawn(x, y, "boost");
return; return;
} }

View File

@@ -232,7 +232,7 @@ const tech = {
if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1) if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1)
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25 if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35;
if (tech.isRerollDamage) dmg *= 1 + 0.038 * powerUps.research.count if (tech.isRerollDamage) dmg *= 1 + 0.03 * powerUps.research.count
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy) if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
@@ -2415,7 +2415,7 @@ const tech = {
}, },
{ {
name: "ground state", name: "ground state",
description: "<strong>+200</strong> maximum <strong class='color-f'>energy</strong><br><strong>50%</strong> passive <strong class='color-f'>energy</strong> generation", description: "<strong>+200</strong> maximum <strong class='color-f'>energy</strong><br><strong>40%</strong> passive <strong class='color-f'>energy</strong> generation",
// description: "reduce <strong class='color-defense'>defense</strong> by <strong>66%</strong><br>you <strong>no longer</strong> passively regenerate <strong class='color-f'>energy</strong>", // description: "reduce <strong class='color-defense'>defense</strong> by <strong>66%</strong><br>you <strong>no longer</strong> passively regenerate <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -2494,7 +2494,7 @@ const tech = {
}, },
{ {
name: "overcharge", name: "overcharge",
description: "<strong>+60</strong> maximum <strong class='color-f'>energy</strong><br><strong>+10%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool", description: "<strong>+66</strong> maximum <strong class='color-f'>energy</strong><br><strong>+6%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2502,9 +2502,9 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.bonusEnergy += 0.6 tech.bonusEnergy += 0.66
m.setMaxEnergy() m.setMaxEnergy()
this.refundAmount += tech.addJunkTechToPool(0.1) this.refundAmount += tech.addJunkTechToPool(0.06)
}, },
refundAmount: 0, refundAmount: 0,
remove() { remove() {
@@ -2518,7 +2518,7 @@ const tech = {
}, },
{ {
name: "Maxwell's demon", name: "Maxwell's demon",
description: "<strong class='color-f'>energy</strong> above your max decays <strong>95%</strong> slower<br><strong>+10%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool", description: "<strong class='color-f'>energy</strong> above your max decays <strong>95%</strong> slower<br><strong>+5%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -2529,7 +2529,7 @@ const tech = {
requires: "energy above your max", requires: "energy above your max",
effect() { effect() {
tech.overfillDrain = 0.92 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87) tech.overfillDrain = 0.92 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87)
this.refundAmount += tech.addJunkTechToPool(0.1) this.refundAmount += tech.addJunkTechToPool(0.05)
}, },
refundAmount: 0, refundAmount: 0,
remove() { remove() {
@@ -3104,7 +3104,7 @@ const tech = {
}, },
{ {
name: "renormalization", name: "renormalization",
description: `<strong>40%</strong> chance to spawn ${powerUps.orb.research(1)}<br>after consuming ${powerUps.orb.research(1)}`, description: `<strong>44%</strong> chance to spawn ${powerUps.orb.research(1)}<br>after consuming ${powerUps.orb.research(1)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -3163,20 +3163,25 @@ const tech = {
{ {
name: "Bayesian statistics", name: "Bayesian statistics",
// description: `for each ${powerUps.orb.research(1)} in your inventory<br><strong>+3.8%</strong> <strong class='color-d'>damage</strong>`, // description: `for each ${powerUps.orb.research(1)} in your inventory<br><strong>+3.8%</strong> <strong class='color-d'>damage</strong>`,
descriptionFunction() { return `<strong>+3.8%</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.research(1)} <em>(${(3.8*powerUps.research.count).toFixed(0)}%)</em>` }, descriptionFunction() { return `<strong>+3%</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.research(1)} <em>(${(3*powerUps.research.count).toFixed(0)}%)</em><br>spawn ${powerUps.orb.research(this.bonusResearch)}` },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return powerUps.research.count > 5 || build.isExperimentSelection return powerUps.research.count > 2 || build.isExperimentSelection
}, },
requires: "at least 6 research", requires: "at least 3 research",
bonusResearch: 3,
effect() { effect() {
powerUps.spawnDelay("research", this.bonusResearch)
tech.isRerollDamage = true; tech.isRerollDamage = true;
}, },
remove() { remove() {
tech.isRerollDamage = false; tech.isRerollDamage = false;
if (this.count) {
powerUps.research.changeRerolls(-this.bonusResearch)
}
} }
}, },
{ {
@@ -3408,7 +3413,7 @@ const tech = {
{ {
name: "exciton", name: "exciton",
descriptionFunction() { descriptionFunction() {
return `<span style = 'font-size:94%;'>after mobs <strong>die</strong> they have a <strong>18%</strong> chance to<br>spawn ${powerUps.orb.boost(1)} that give <strong>+${(powerUps.boost.damage*100).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds</span>` return `<span style = 'font-size:94%;'>after mobs <strong>die</strong> they have a <strong>16%</strong> chance to<br>spawn ${powerUps.orb.boost(1)} that give <strong>+${(powerUps.boost.damage*100).toFixed(0)}%</strong> <strong class='color-d'>damage</strong> for <strong>${(powerUps.boost.duration/60).toFixed(0)}</strong> seconds</span>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5003,7 +5008,7 @@ const tech = {
{ {
name: "missile-bot", name: "missile-bot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">missile-bot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">missile-bot</a>`,
description: "gain a <strong class='color-bot'>bot</strong> that fires <strong>missiles</strong> at mobs<br>remove your <strong>missile gun</strong>", description: `use ${powerUps.orb.research(1)}to trade your <strong>missile</strong> <strong class='color-g'>gun</strong><br>for a <strong class='color-bot'>bot</strong> that fires <strong>missiles</strong>`,
isGunTech: true, isGunTech: true,
isRemoveGun: true, isRemoveGun: true,
maxCount: 1, maxCount: 1,
@@ -5013,13 +5018,16 @@ const tech = {
isBot: true, isBot: true,
isBotTech: true, isBotTech: true,
allowed() { allowed() {
return tech.haveGunCheck("missiles", false) && tech.missileFireCD === 45 return tech.haveGunCheck("missiles", false) && tech.missileFireCD === 45 && (build.isExperimentSelection || powerUps.research.count > 0)
}, },
requires: "missiles, not launch system", requires: "missiles, not launch system",
effect() { effect() {
tech.missileBotCount++; tech.missileBotCount++;
b.missileBot(); b.missileBot();
if (tech.haveGunCheck("missiles", false)) b.removeGun("missiles") //remove your last gun if (tech.haveGunCheck("missiles", false)) b.removeGun("missiles") //remove your last gun
for (let i = 0; i < 1; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
if (this.count) { if (this.count) {
@@ -5027,6 +5035,7 @@ const tech = {
b.clearPermanentBots(); b.clearPermanentBots();
b.respawnBots(); b.respawnBots();
if (!tech.haveGunCheck("missiles", false)) b.giveGuns("missiles") if (!tech.haveGunCheck("missiles", false)) b.giveGuns("missiles")
powerUps.research.changeRerolls(1)
} }
} }
}, },
@@ -5147,25 +5156,25 @@ const tech = {
}, },
{ {
name: "shaped charge", name: "shaped charge",
description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`, description: `use ${powerUps.orb.research(3)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`,
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 3) && (tech.haveGunCheck("missiles") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)) return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 2) && (tech.haveGunCheck("missiles") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
}, },
requires: "an explosive damage source, not electric reactive armor", requires: "an explosive damage source, not electric reactive armor",
effect() { effect() {
tech.isSmartRadius = true; tech.isSmartRadius = true;
for (let i = 0; i < 4; i++) { for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
}, },
remove() { remove() {
tech.isSmartRadius = false; tech.isSmartRadius = false;
if (this.count > 0) powerUps.research.changeRerolls(4) if (this.count > 0) powerUps.research.changeRerolls(3)
} }
}, },
{ {
@@ -5921,7 +5930,7 @@ const tech = {
}, },
{ {
name: "fault tolerance", name: "fault tolerance",
description: "remove your <strong>drone gun</strong><br>spawn <strong>4</strong> <strong>drones</strong> that last <strong>forever</strong>", description: `use ${powerUps.orb.research(2)}to trade your <strong>drone</strong> <strong class='color-g'>gun</strong><br>for <strong>5</strong> <strong>drones</strong> that last <strong>forever</strong>`,
isGunTech: true, isGunTech: true,
isRemoveGun: true, isRemoveGun: true,
maxCount: 1, maxCount: 1,
@@ -5929,11 +5938,11 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1 && !tech.isDronesTravel return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1 && !tech.isDronesTravel && (build.isExperimentSelection || powerUps.research.count > 1)
}, },
requires: "drones, not drone repair, anti-shear topology, autonomous navigation", requires: "drones, not drone repair, anti-shear topology, autonomous navigation",
effect() { effect() {
const num = 4 const num = 5
tech.isForeverDrones += num tech.isForeverDrones += num
if (tech.haveGunCheck("drones", false)) b.removeGun("drones") if (tech.haveGunCheck("drones", false)) b.removeGun("drones")
//spawn drones //spawn drones
@@ -5948,15 +5957,19 @@ const tech = {
bullet[bullet.length - 1].endCycle = Infinity bullet[bullet.length - 1].endCycle = Infinity
} }
} }
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
tech.isForeverDrones = 0 tech.isForeverDrones = 0
if (this.count && !tech.haveGunCheck("drones", false)) b.giveGuns("drones") if (this.count && !tech.haveGunCheck("drones", false)) b.giveGuns("drones")
if (this.count > 0) powerUps.research.changeRerolls(2)
} }
}, },
{ {
name: "surfactant", name: "surfactant",
description: "trade your <strong>foam gun</strong> for <strong>2</strong> <strong class='color-bot'>foam-bots</strong><br><strong>upgrade</strong> all bots to foam", description: `use ${powerUps.orb.research(2)}to trade your <strong>foam</strong> <strong class='color-g'>gun</strong><br>for <strong>3</strong> <strong class='color-bot'>foam-bots</strong> and <strong>foam-bot upgrade</strong>`,
isGunTech: true, isGunTech: true,
isRemoveGun: true, isRemoveGun: true,
maxCount: 1, maxCount: 1,
@@ -5966,9 +5979,9 @@ const tech = {
isBot: true, isBot: true,
isBotTech: true, isBotTech: true,
isNonRefundable: true, isNonRefundable: true,
requires: "at least 2 guns, foam gun, bot upgrades, fractionation, pressure vessel", requires: "foam gun, bot upgrades, fractionation, pressure vessel",
allowed() { allowed() {
return b.inventory.length > 1 && tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.isFoamPressure return tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.isFoamPressure && (build.isExperimentSelection || powerUps.research.count > 1)
}, },
effect() { effect() {
tech.giveTech("foam-bot upgrade") tech.giveTech("foam-bot upgrade")
@@ -5978,6 +5991,9 @@ const tech = {
} }
simulation.makeTextLog(`tech.isFoamBotUpgrade = true`) simulation.makeTextLog(`tech.isFoamBotUpgrade = true`)
if (tech.haveGunCheck("foam", false)) b.removeGun("foam") if (tech.haveGunCheck("foam", false)) b.removeGun("foam")
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
// if (this.count) { // if (this.count) {
@@ -5985,6 +6001,7 @@ const tech = {
// b.respawnBots(); // b.respawnBots();
// if (!tech.haveGunCheck("foam")) b.giveGuns("foam") // if (!tech.haveGunCheck("foam")) b.giveGuns("foam")
// } // }
// if (this.count > 0) powerUps.research.changeRerolls(2)
} }
}, },
{ {
@@ -6086,7 +6103,7 @@ const tech = {
}, },
{ {
name: "foam fractionation", name: "foam fractionation",
description: "if you have below <strong>300</strong> <strong class='color-ammo'>ammo</strong><br><strong>+100%</strong> <strong>foam</strong> gun bubble <strong>size</strong>", description: "if you have below <strong>300</strong> <strong class='color-ammo'>ammo</strong><br><strong>+100%</strong> <strong>foam</strong> <strong class='color-g'>gun</strong> bubble <strong>size</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6132,7 +6149,7 @@ const tech = {
}, },
{ {
name: "pressure vessel", name: "pressure vessel",
description: "build up <strong>charge</strong> while firing <strong>foam</strong> gun<br>after firing <strong>discharge</strong> <strong>foam</strong> bubbles", description: "build up <strong>charge</strong> while firing <strong>foam</strong> <strong class='color-g'>gun</strong><br>after firing <strong>discharge</strong> <strong>foam</strong> bubbles",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6532,7 +6549,7 @@ const tech = {
}, },
{ {
name: "lens", name: "lens",
description: "<strong>+150%</strong> <strong class='color-laser'>laser</strong> gun <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>90°</strong> arc circular lens", //<span style='font-size: 125%;'>π</span> / 2</strong> description: "<strong>+150%</strong> <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong> <strong class='color-d'>damage</strong> if it passes<br>through a revolving <strong>90°</strong> arc circular lens", //<span style='font-size: 125%;'>π</span> / 2</strong>
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6597,7 +6614,7 @@ const tech = {
}, },
{ {
name: "diffraction grating", name: "diffraction grating",
description: `<strong>+1</strong> diverging <strong class='color-laser'>laser</strong> gun beam`, description: `<strong>+1</strong> diverging <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong> beam`,
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -6621,7 +6638,7 @@ const tech = {
{ {
name: "diffuse beam", name: "diffuse beam",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Diffuser_(optics)' class="link">diffuse beam</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Diffuser_(optics)' class="link">diffuse beam</a>`,
description: "<strong class='color-laser'>laser</strong> gun beam is <strong>wider</strong> and doesn't <strong>reflect</strong><br><strong>+220%</strong> <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong>", description: "<strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong> beam is <strong>wider</strong> and doesn't <strong>reflect</strong><br><strong>+220%</strong> <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6646,7 +6663,7 @@ const tech = {
}, },
{ {
name: "output coupler", name: "output coupler",
description: "<strong>+30%</strong> <strong class='color-laser'>laser</strong> gun beam <strong>width</strong><br><strong>+30%</strong> <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong>", description: "<strong>+30%</strong> <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong> beam <strong>width</strong><br><strong>+30%</strong> <strong class='color-laser'>laser</strong> <strong class='color-d'>damage</strong>",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -6671,7 +6688,7 @@ const tech = {
}, },
{ {
name: "slow light", name: "slow light",
description: "<strong class='color-laser'>laser</strong> gun beam is <strong>spread</strong> into your recent <strong>past</strong><br><strong>+300%</strong> total beam <strong class='color-d'>damage</strong>", description: "<strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong> beam is <strong>spread</strong> into your recent <strong>past</strong><br><strong>+300%</strong> total beam <strong class='color-d'>damage</strong>",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -7412,7 +7429,7 @@ const tech = {
{ {
name: "plasma-bot", name: "plasma-bot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">plasma-bot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">plasma-bot</a>`,
description: "remove your <strong class='color-f'>field</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>", description: `use ${powerUps.orb.research(2)}to trade your <strong class='color-f'>field</strong><br>for a <strong class='color-bot'>bot</strong> that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7421,7 +7438,7 @@ const tech = {
isBot: true, isBot: true,
isBotTech: true, isBotTech: true,
allowed() { allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && !tech.isPlasmaBall && !tech.isExtruder return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && !tech.isPlasmaBall && !tech.isExtruder && (build.isExperimentSelection || powerUps.research.count > 1)
}, },
requires: "plasma torch, not extruder, plasma ball", requires: "plasma torch, not extruder, plasma ball",
effect() { effect() {
@@ -7432,6 +7449,9 @@ const tech = {
document.getElementById("field-0").classList.add("build-field-selected"); document.getElementById("field-0").classList.add("build-field-selected");
} }
m.setField("field emitter") m.setField("field emitter")
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
if (this.count > 0) { if (this.count > 0) {
@@ -7445,6 +7465,7 @@ const tech = {
document.getElementById("field-" + m.fieldMode).classList.add("build-field-selected"); document.getElementById("field-" + m.fieldMode).classList.add("build-field-selected");
} }
} }
powerUps.research.changeRerolls(2)
} }
} }
}, },
@@ -8370,6 +8391,32 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "startle response",
description: `if a threat is nearby, activate a ${powerUps.orb.boost(1)}<br>and lock your mouse until you press escape`,
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
isNonRefundable: true,
allowed: () => true,
requires: "",
effect() {
// tech.damage *= 1.33
setInterval(() => {
if (powerUps.boost.endCycle < m.cycle && !simulation.paused && m.alive) {
for (let i = 0; i < mob.length; i++) {
if (mob[i].distanceToPlayer2() < 400000) { //650
canvas.requestPointerLock();
powerUps.boost.effect();
break
}
}
}
}, 2000);
},
remove() {}
},
{ {
name: "closed timelike curve", name: "closed timelike curve",
description: "spawn 5 <strong class='color-f'>field</strong> power ups, but every 12 seconds<br>teleport a second into your future or past", description: "spawn 5 <strong class='color-f'>field</strong> power ups, but every 12 seconds<br>teleport a second into your future or past",

View File

@@ -1,37 +1,19 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
plasma-bot does 15% more damage, but costs 2 research
fault tolerance 4->5 forever drones, but costs 2 research
surfactant 2->3 foam bots, but costs 2 research
missile-bot costs 1 research
shaped charge 4->3 research cost
renormalization 40->44% chance to refund research
exciton 18->16% chance to spawn
ground state 50->40% reduced energy regen
Bayesian statistics 3.8->3% damage per research, and spawns 3 research
tech: junk DNA - +53% spore/worm/flea damage per JUNK tech you have, +50% JUNK added to tech pool JUNK tech: startle response - if mobs are near boost damage, and lock mouse until you press escape
tech: pigeonhole principle - +31% damage for each gun you have, while a chosen gun is active
chosen gun cycles each level
syncs well with generalist
heuristics 30->25% fire rate, and now spawns a gun
arsenal gives 13->22% damage per gun, but no longer counts your current gun
active cooling gives 18->28% fire rate per gun, but no longer counts your current gun
supply chain adds 4% JUNK
dead reckoning 36->50% damage
alternator harpoon 60->80% energy cost reduction
quickly releasing the fire button retracts harpoon early
JUNK tech - circular symmetry - ship gets 200% damage, ship only faces forward but you can rotate the universe
several bug fixes
coupling for molecular assembler 5->8 energy per second
but also fixed a bug where coupling was giving 10x regen
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
lock mouse to the window until you press escape
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
canvas.requestPointerLock()
exitPointerLock
toggle off and on when:
you die and start a game
when choosing?
If this doesn't work it could at least be a fun JUNK tech
run canvas direct pixel editing while game is paused run canvas direct pixel editing while game is paused
just update once every second? just update once every second?
if it uses too much processing have a setting to toggle it off if it uses too much processing have a setting to toggle it off
@@ -44,6 +26,14 @@ for tech power ups no tech options are displayed until you research once
or display only JUNK until you research once or display only JUNK until you research once
increase the number of options after each research increase the number of options after each research
Tech: Grandfather Paradox - After rewinding, +300 damage during rewinded time
maybe instead of +damage spawn a copy of player that shoots at things?
how... there is no way to reproduce firing
Requires: CPT symmetry, retrocausality
CPT adjacent tech is actually a bit too strong right now, maybe nerf a bit after testing
When receiving damage, in addition to becoming invulnerable to attacks, also become intangible for the set period of time
tech increase max energy and energy to 5000, but you can no longer regen energy through any process tech increase max energy and energy to 5000, but you can no longer regen energy through any process
it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing