mantisBoss flashes for a second before it drops invulnerability
removed parasitism - it's too similar to invulnerability tech
invariant no longer drains energy while wormhole time is paused
  added 1 research cost
added secret combo to change molecular assembler mode

bug fixes
  issue with constraint: "mob death heals mobs"
    mob health was becoming NaN, this was infecting other values like player energy
  entering a seed in settings wasn't giving the same results as a randomly generated seeds
    also removed some random code that was using seeded shuffle, but didn't need to
      converted it to non seeded random shuffle with .sort(() => Math.random() - 0.5);
This commit is contained in:
landgreen
2025-01-18 17:00:10 -08:00
parent 1040d1ff7e
commit c9a5ab91b8
11 changed files with 2347 additions and 2363 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -3160,7 +3160,7 @@ const b = {
if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
!(
(m.health > 0.93 * m.maxHealth && !tech.isDroneGrab && powerUp[i].name === "heal") ||
(m.health > 0.94 * m.maxHealth && !tech.isOverHeal && !tech.isDroneGrab && powerUp[i].name === "heal") ||
(tech.isSuperDeterminism && powerUp[i].name === "field") ||
((tech.isEnergyNoAmmo || b.inventory.length === 0) && powerUp[i].name === "ammo")
)
@@ -3192,7 +3192,7 @@ const b = {
let closeDist = Infinity;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (!(
(m.health > 0.93 * m.maxHealth && !tech.isDroneGrab && powerUp[i].name === "heal") ||
(m.health > 0.94 * m.maxHealth && !tech.isOverHeal && !tech.isDroneGrab && powerUp[i].name === "heal") ||
(tech.isSuperDeterminism && powerUp[i].name === "field") ||
((tech.isEnergyNoAmmo || b.inventory.length === 0) && powerUp[i].name === "ammo")
)) {

View File

@@ -28,11 +28,11 @@ Math.seededRandom = function (min = 0, max = 1) { // in order to work 'Math.seed
// console.log(Math.seed)
function shuffle(array) {
function seededShuffle(array) {
var currentIndex = array.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
// While there remain elements
while (0 !== currentIndex) {
// Pick a remaining element...
// randomIndex = Math.floor(Math.random() * currentIndex);
@@ -542,7 +542,7 @@ ${simulation.difficultyMode > 4 ? `<details id="constraints-details" style="padd
<details id = "console-log-details" style="padding: 0 8px;">
<summary>console log</summary>
<div class="pause-details">
<div class="pause-grid-module" style="background-color: rgba(255,255,255,0.3);font-size: 0.8em;">${document.getElementById("text-log").innerHTML}</div>
<div class="pause-grid-module" style=" background-color: #e2e9ec;font-size: 0.8em;">${document.getElementById("text-log").innerHTML}</div>
</div>
</details>
</div>`
@@ -1205,6 +1205,7 @@ const input = {
left: false,
right: false,
isPauseKeyReady: true,
// lastDown: null,
key: {
fire: "KeyF",
field: "Space",
@@ -1379,6 +1380,7 @@ window.addEventListener("keyup", function (event) {
});
window.addEventListener("keydown", function (event) {
// input.lastDown = event.code
// console.log(event.code)
switch (event.code) {
case input.key.right:

View File

@@ -22,7 +22,7 @@ const level = {
// simulation.isHorizontalFlipped = true
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// level.levelsCleared = 10
// level.levelsCleared = 9
// level.updateDifficulty()
// tech.giveTech("performance")
// m.maxHealth = m.health = 100000000
@@ -33,7 +33,7 @@ const level = {
// tech.tech[297].frequency = 100
// tech.addJunkTechToPool(0.5)
// m.couplingChange(10)
// m.setField("negative mass") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.setField("wormhole") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.energy = 0
// powerUps.research.count = 3
// tech.isHookWire = true
@@ -58,7 +58,7 @@ const level = {
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("interest") });
// for (let i = 0; i < 1; i++) tech.giveTech("interest")
// m.lastKillCycle = m.cycle
// for (let i = 0; i < 7; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 7; i++) powerUps.directSpawn(450, -50, "field");
// for (let i = 0; i < 7; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 250, "research", false);
// spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
// level.testing();
@@ -810,14 +810,14 @@ const level = {
if (document.getElementById("seed").value) { //check for player entered seed in settings
Math.initialSeed = String(document.getElementById("seed").value)
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it
}
Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed
if (simulation.isTraining) {
simulation.isHorizontalFlipped = false
level.levels = level.trainingLevels.slice(0) //copy array, not by just by assignment
if (simulation.isCommunityMaps) level.trainingLevels.push("diamagnetism")
} else { //add remove and shuffle levels for the normal game (not training levels)
} else {
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
if (simulation.isCommunityMaps) {
level.levels = level.levels.concat(level.communityLevels)
@@ -825,7 +825,7 @@ const level = {
} else {
simulation.isHorizontalFlipped = (Math.seededRandom() < 0.5) ? true : false //if true, some maps are flipped horizontally
}
level.levels = shuffle(level.levels); //shuffles order of maps with seeded random
level.levels = seededShuffle(level.levels); //shuffles order of maps with seeded random
level.levels.length = 9 //remove any extra levels past 9
pick = ["interferometer", "factory", "reservoir"]
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, pick[Math.floor(Math.random() * pick.length)]); //add level to the back half of the randomized levels list
@@ -3533,7 +3533,7 @@ const level = {
const stationList = [] //use to randomize station order
for (let i = 1, totalNumberOfStations = 10; i < totalNumberOfStations; ++i) stationList.push(i) //!!!! update station number when you add a new station
shuffle(stationList);
stationList.sort(() => Math.random() - 0.5);
stationList.splice(0, 3); //remove some stations to keep it to 4 stations
stationList.unshift(0) //add index zero to the front of the array
@@ -6690,14 +6690,14 @@ const level = {
//3x2: 4 short rooms (3000x1500), 1 double tall room (3000x3000)
//rooms
let rooms = ["exit", "loot", "enter", "empty"]
rooms = shuffle(rooms); //shuffles array order
rooms.sort(() => Math.random() - 0.5);
//look... you and I both know there is a better way to do this, but it works so I'm gonna focus on other things
while ( //makes sure that the exit and entrance aren't both on the same floor
(rooms[0] === "enter" && rooms[2] === "exit") ||
(rooms[2] === "enter" && rooms[0] === "exit") ||
(rooms[1] === "enter" && rooms[3] === "exit") ||
(rooms[3] === "enter" && rooms[1] === "exit")
) rooms = shuffle(rooms); //shuffles array order
) rooms.sort(() => Math.random() - 0.5);
for (let i = 0; i < rooms.length; i++) {
if (rooms[i] === "enter") rooms[i] = enter
if (rooms[i] === "exit") rooms[i] = exit
@@ -6764,7 +6764,7 @@ const level = {
rooms[3]()
},
]
columns = shuffle(columns) //********************************* RUN THIS LINE IN THE FINAL VERSION ***************************************
columns.sort(() => Math.random() - 0.5);
for (let i = 0; i < 3; i++) {
if (i === 0) {
isDoorLeft = false
@@ -7054,7 +7054,7 @@ const level = {
};
powerUps.spawnStartingPowerUps(1875, -3075);
const powerUpPos = shuffle([{ //no debris on this level but 2 random spawn instead
const powerUpPos = [{ //no debris on this level but 2 random spawn instead
x: -150,
y: -1775
}, {
@@ -7066,7 +7066,8 @@ const level = {
}, {
x: 1325,
y: -150
}]);
}];
powerUpPos.sort(() => Math.random() - 0.5);
powerUps.chooseRandomPowerUp(powerUpPos[0].x, powerUpPos[0].y);
powerUps.chooseRandomPowerUp(powerUpPos[1].x, powerUpPos[1].y);
//outer wall
@@ -8858,7 +8859,8 @@ const level = {
// spawn.bodyRect(312, -100, 25, 100);
spawn.bodyRect(1450, -300, 150, 50);
const xPos = shuffle([600, 1250, 2000]);
const xPos = [600, 1250, 2000];
xPos.sort(() => Math.random() - 0.5);
spawn.mapRect(xPos[0], -200, 300, 100);
spawn.mapRect(xPos[1], -250, 300, 300);
spawn.mapRect(xPos[2], -150, 300, 200);

View File

@@ -1069,7 +1069,11 @@ const mobs = {
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000
dmg *= this.damageReduction
//energy and heal drain should be calculated after damage boosts
if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon * level.isReducedRegen
if (tech.energySiphon && this.isDropPowerUp && m.immuneCycle < m.cycle) {
//dmg !== Infinity &&
const regen = Math.min(this.health, dmg) * tech.energySiphon * level.isReducedRegen
if (!isNaN(regen) && regen !== Infinity) m.energy += regen
}
dmg /= Math.sqrt(this.mass)
}
@@ -1129,7 +1133,7 @@ const mobs = {
for (let i = 0; i < mob.length; i++) {
if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 && mob[i].alive) { //700
if (mob[i].health < 1) {
mob[i].health += 0.33 + this.isBoss
mob[i].health += 0.33
if (mob[i].health > 1) mob[i].health = 1
simulation.drawList.push({
x: mob[i].position.x,

File diff suppressed because it is too large Load Diff

View File

@@ -1653,6 +1653,7 @@ const powerUps = {
if (b.inventory.length === 0) {
powerUps.spawn(x, y, "gun", false); //first gun
} else if (tech.totalCount === 0) { //first tech
powerUps.spawn(x - 22, y - 50, "ammo", false); //some ammo
powerUps.spawn(x, y, "tech", false);
} else if (b.inventory.length === 1) { //second gun or extra ammo
if (Math.random() < 0.4) {

View File

@@ -987,7 +987,7 @@ const simulation = {
} else {
Composite.add(engine.world, [player])
}
shuffle(level.constraint)
seededShuffle(level.constraint)
level.populateLevels()
input.endKeySensing();
simulation.ephemera = []

View File

@@ -745,7 +745,7 @@ const spawn = {
// exit() { },
// },
]
shuffle(me.mode); //THIS SHOULD NOT BE COMMENTED OUT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
me.mode.sort(() => Math.random() - 0.5);
me.do = function () {
this.fill = `hsl(${360 * Math.sin(this.cycle * 0.011)},${80 + 20 * Math.sin(this.cycle * 0.004)}%,${60 + 20 * Math.sin(this.cycle * 0.009)}%)`
if (this.health < 1) {
@@ -1771,6 +1771,7 @@ const spawn = {
powerUps.spawn(me.position.x, me.position.y, "heal");
powerUps.spawn(me.position.x, me.position.y, "ammo");
powerUps.spawn(me.position.x, me.position.y, "ammo");
powerUps.spawn(me.position.x, me.position.y, "ammo");
} else if (!m.isCloak) {
me.foundPlayer();
}
@@ -2683,22 +2684,24 @@ const spawn = {
this.seePlayerByHistory()
this.invulnerabilityCountDown--
if (this.isInvulnerable) {
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) {
let vertices = this.babyList[i].vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
if (this.invulnerabilityCountDown > 90 || this.invulnerabilityCountDown % 20 > 10) {
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) {
let vertices = this.babyList[i].vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
}
}
ctx.lineWidth = 3 + 0.2 * Math.min(this.invulnerabilityCountDown, 90) + 5 * Math.random()
ctx.strokeStyle = `rgba(255,255,255,${0.4 + 0.4 * Math.random()})`;
ctx.stroke();
}
ctx.lineWidth = 13 + 5 * Math.random();
ctx.strokeStyle = `rgba(255,255,255,${0.5 + 0.2 * Math.random()})`;
ctx.stroke();
if (this.invulnerabilityCountDown < 0) {
this.invulnerabilityCountDown = 110
this.isInvulnerable = false
@@ -2711,7 +2714,7 @@ const spawn = {
}
}
} else if (this.invulnerabilityCountDown < 0) {
this.invulnerabilityCountDown = 120 + 9 * simulation.difficulty
this.invulnerabilityCountDown = 240 + 5 * simulation.difficulty
this.isInvulnerable = true
if (this.damageReduction) this.startingDamageReduction = this.damageReduction
this.damageReduction = 0

View File

@@ -271,7 +271,6 @@ const tech = {
if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 3
if (tech.isPowerUpDamage) dmg *= 1 + 0.07 * powerUp.length
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.9
if (tech.offGroundDamage && !m.onGround) dmg *= tech.offGroundDamage
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
@@ -1018,7 +1017,7 @@ const tech = {
{
name: "Pareto efficiency",
descriptionFunction() {
return `all you ${powerUps.orb.gun()} randomly get<br><strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
return `all your ${powerUps.orb.gun()} randomly get<br><strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
},
maxCount: 1,
count: 0,
@@ -1033,7 +1032,7 @@ const tech = {
let options = []
for (let i = 0; i < b.inventory.length; i++) options.push(b.inventory[i])
options = shuffle(options)
options.sort(() => Math.random() - 0.5);
for (let i = 0; i < options.length; i++) {
const index = options[i]
const scale = (i < options.length / 2) ? 4 : 0.25
@@ -2758,7 +2757,7 @@ const tech = {
},
{
name: "Pauli exclusion",
description: `for <strong>7</strong> seconds after mob <strong>collisions</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
description: `for <strong>7</strong> seconds after mob <strong>collisions</strong><br>gain <strong class="color-invulnerable">invulnerbility</strong> and <em style="opacity: 0.3;">blocked <strong class='color-f'>energy</strong> regen</em>`,
maxCount: 9,
count: 0,
frequency: 1,
@@ -2777,7 +2776,7 @@ const tech = {
},
{
name: "spin-statistics theorem",
description: `for <strong>1.9</strong> seconds out of every <strong>7</strong> seconds<br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
description: `for <strong>1.9</strong> seconds out of every <strong>7</strong> seconds<br>gain <strong class="color-invulnerable">invulnerbility</strong> and <em style="opacity: 0.3;">blocked <strong class='color-f'>energy</strong> regen</em>`,
maxCount: 3,
count: 0,
frequency: 1,
@@ -2795,7 +2794,7 @@ const tech = {
},
{
name: "fermion",
description: `for <strong>5</strong> seconds after mobs <strong>die</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
description: `if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>gain <strong class="color-invulnerable">invulnerbility</strong> and <em style="opacity: 0.3;">blocked <strong class='color-f'>energy</strong> regen</em>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3009,9 +3008,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isDamageAfterKillNoRegen
return true
},
requires: "not parasitism",
requires: "",
effect() {
tech.isCrouchRegen = true; //only used to check for requirements
m.regenEnergy = function () {
@@ -3042,29 +3041,6 @@ const tech = {
tech.energySiphon = 0;
}
},
{
name: "parasitism",
description: "if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br><strong>2x</strong> <strong class='color-d'>damage</strong>, no passive <strong class='color-f'>energy</strong> generation",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isCrouchRegen
},
requires: "not inductive charging",
effect() {
tech.isDamageAfterKillNoRegen = true;
m.regenEnergy = function () {
if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle) && m.fieldCDcycle < m.cycle) m.energy += m.fieldRegen * level.isReducedRegen;
if (m.energy < 0) m.energy = 0
}
},
remove() {
if (this.count) m.regenEnergy = m.regenEnergyDefault
tech.isDamageAfterKillNoRegen = false;
}
},
{
name: "waste heat recovery",
description: "if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>generate <strong>0.05x</strong> maximum <strong class='color-f'>energy</strong> every second",
@@ -4769,7 +4745,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups
if (tech.tech[i].count && !tech.tech[i].isInstant) pool.push(i)
}
pool = shuffle(pool); //shuffles order of maps
pool.sort(() => Math.random() - 0.5);
let removeCount = 0
for (let i = 0, len = pool.length * 0.5; i < len; i++) removeCount += tech.removeTech(pool[i])
this.damage = this.damagePerRemoved * removeCount
@@ -8965,22 +8941,31 @@ const tech = {
},
{
name: "invariant",
description: "while placing your <strong class='color-worm'>wormhole</strong><br>use <strong class='color-f'>energy</strong> to <strong>pause</strong> time",
cost: 1,
descriptionFunction() {
return `use ${powerUps.orb.research(this.cost)}<br><strong>pause</strong> time while placing your <strong class='color-worm'>wormhole</strong>`
},
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldMode === 9 && !tech.isNoDraftPause
return m.fieldMode === 9 && !tech.isNoDraftPause && (build.isExperimentSelection || powerUps.research.count > this.cost - 1)
},
requires: "wormhole, not eternalism",
effect() {
tech.isWormHolePause = true
for (let i = 0; i < this.cost; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
remove() {
if (tech.isWormHolePause && m.isTimeDilated) m.wakeCheck();
tech.isWormHolePause = false
if (this.count) {
powerUps.research.changeRerolls(this.cost)
}
}
},
{
@@ -9031,7 +9016,7 @@ const tech = {
allowed() {
return m.fieldMode === 9 && !tech.isFreeWormHole
},
requires: "wormhole, not charmed baryons",
requires: "wormhole, not holographic principle",
effect() {
tech.isWormholeMapIgnore = true
},
@@ -10044,8 +10029,8 @@ const tech = {
},
requires: "",
effect() {
// const colors = shuffle(["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"])
const colors = shuffle([powerUps.research.color, powerUps.heal.color, powerUps.ammo.color, powerUps.ammo.color, powerUps.field.color, powerUps.gun.color])
const colors = [powerUps.research.color, powerUps.heal.color, powerUps.ammo.color, powerUps.ammo.color, powerUps.field.color, powerUps.gun.color]
colors.sort(() => Math.random() - 0.5);
powerUps.research.color = colors[0]
powerUps.heal.color = colors[1]
powerUps.ammo.color = colors[2]
@@ -10075,37 +10060,7 @@ const tech = {
}
}
},
remove() {
// const colors = ["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"] //no shuffle
// powerUps.research.color = colors[0]
// powerUps.heal.color = colors[1]
// powerUps.ammo.color = colors[2]
// powerUps.field.color = colors[3]
// powerUps.tech.color = colors[4]
// powerUps.gun.color = colors[5]
// for (let i = 0; i < powerUp.length; i++) {
// switch (powerUp[i].name) {
// case "research":
// powerUp[i].color = colors[0]
// break;
// case "heal":
// powerUp[i].color = colors[1]
// break;
// case "ammo":
// powerUp[i].color = colors[2]
// break;
// case "field":
// powerUp[i].color = colors[3]
// break;
// case "tech":
// powerUp[i].color = colors[4]
// break;
// case "gun":
// powerUp[i].color = colors[5]
// break;
// }
// }
}
remove() { }
},
{
name: "emergency broadcasting",
@@ -10519,7 +10474,7 @@ const tech = {
},
requires: "",
effect() {
String.prototype.shuffle = function () {
String.prototype.shuf = function () {
var a = this.split(""),
n = a.length;
@@ -10532,7 +10487,7 @@ const tech = {
return a.join("");
}
for (let i = 0, len = tech.tech.length; i < len; i++) tech.tech[i].name = tech.tech[i].name.shuffle()
for (let i = 0, len = tech.tech.length; i < len; i++) tech.tech[i].name = tech.tech[i].name.shuf()
},
remove() { }
},
@@ -12190,7 +12145,6 @@ const tech = {
isDuplicateMobs: null,
isDynamoBotUpgrade: null,
isBlockPowerUps: null,
isDamageAfterKillNoRegen: null,
isHarmReduceNoKill: null,
isSwitchReality: null,
isResearchReality: null,

143
todo.txt
View File

@@ -1,99 +1,78 @@
******************************************************** NEXT PATCH **************************************************
tech: demineralization - after mobs die gain 0.85x damage taken, effect stacks, but fades 10% every second
tech: remineralization - after mobs die gain 1.08x damage, effect stacks, but fades 10% every second
tech: equivalence principle - negative mass field doesn't cost energy
new JUNK tech: aerodynamics
interferometer
slower elevator and lasers
wider side ledges
large laser blocking blocks
flocculation
fewer mobs
it's easier to get out of the slime
pavilion
move vanish elements
easier traversal
secret tunnel
removed debris, but added power ups and blocks
corridor
limited to bosses that don't interact with the movers poorly
gravitron, substructure, corridor, interferometer
added more heal and ammo power ups to match other levels
because some newer levels are zoomed out more
laser max range is 3000->5000
nails last 1/3 of a second longer
bosses spawn an extra ammo power up
and 2 extra ammo on the hardest 2 difficulties
slasher mob's laserSwords will now damage a cloaked player
constraint announcement text looks more like computer code style to match game theme
foam recoil is back: 1->0.7x horizontal force and 2->4.3x vertical up force
this makes it less annoying to horizontally and easier to kinda fly/float
negative mass field damage reduction 0.4->0.5x
holographic principle no longer slows player movement
added 2 research cost
fermion gives 6->5 seconds of invulnerability after mobs die
stability 0.2->0.1x damage taken at max health
non-Newtonian armor 0.3->0.4x damage taken after collisions
Zeno's paradox 0.15->0.2x damage taken
annihilation energy cost 10->8 to destroy mobs after collisions
radiative equilibrium damage is 3->4x for 8->4 seconds
aerostat can be taken 1->3 times
dynamic equilibrium damage increased by 6->8x damage per last damage taken
aerostat no longer has 0.9x damage for being on the ground
launch system 1.2->1.3x ammo for missiles
research says that repeatedly entering alternate realities builds up some positive effects
Hilbert space 4x->3x damage
Ψ(t) collapse 6->4 research on boss death
transdimensional worms: 50% chance for a second worm per block in wormhole
wormhole 7->8 energy regen per second
hidden-variable theory 1.15->1.2 damage after choosing a field tech
ghoster mobs are less likely to get knocked far away from the player for long periods of time
mantisBoss flashes for a second before it drops invulnerability
removed parasitism - it's too similar to invulnerability tech
invariant no longer drains energy while wormhole time is paused
added 1 research cost
added secret combo to change molecular assembler mode
bug fixes
dynamic equilibrium was set to 100 times higher frequency then normal
when constraints hide health bar's it's now hidden in the pause menu
mobs aiming at cloaked player
snakeBoss more intelligently chases player for a few seconds
pulsarBoss aims at player's history 3 seconds in past
pulsar will not stop firing
but it will still not fire at cloaked player
issue with constraint: "mob death heals mobs"
mob health was becoming NaN, this was infecting other values like player energy
entering a seed in settings wasn't giving the same results as a randomly generated seeds
also removed some random code that was using seeded shuffle, but didn't need to
converted it to non seeded random shuffle with .sort(() => Math.random() - 0.5);
******************************************************** BUGS ********************************************************
figure out why seeded random isn't making runs the same:
shuffle is being used for a wide variety of things that don't need a seeded random
make two shuffle functions?
check which of these is working
level order
is flipped
constraint order
mob type order
boss order
gun, field, tech options
make field options offered precalculated so it doesn't depend on player choices?
generate all constraints at the start of the game
doesn't seem to be determined by the seed...
display future constraints in pause menu?
player can become crouched while not touching the ground if they exit the ground while crouched
*********************************************************** TODO *****************************************************
use ←↑→↓↖↗↘↙ combos to allow fields to have special actions
!!should this be wasd, arrows, or both?
how to limit spam?
on cooldown
timer or once per level
energy cost
research cost
toggle modes
combos are listed in white text in field description, and console message when getting field
shows up on highlight, and mouse over in experiment mode
field ideas:
standing wave
push mobs away are any distance
pull mobs towards you
perfect diamagnetism
negative mass
molecular assembler - done
plasma torch
time dilation
metamaterial cloaking
pilot wave
spawn blocks
wormhole
shoot out all the blocks that were sucked in this level (maybe cap at like 10?, cap with energy spent to fire)
are block sizes stored properly? because they shrink before they get eaten...
store vertices on the body object if one does already exists
after eating store the saved vertices
where to fire blocks from and in what direction?
target mobs?
fire from player (and draw a wormhole looking graphic)
grappling hook
new level idea: escort mission
player has to stay near something that moves slowly through the level
maybe only a zone around the escort is safe
safe from?
lasers
slime
radiation
use line of site vision?
is it going to feel too slow?
where to put in level order?
random option instead of reactor?
normal level?
4th hard level?
already too many hard options
you could put in 2 hard levels in the level list
make the style look like substructure, that level looks great
use the motion sense lasers
tech synergy ideas
a tech that spawns mobs that the player can use to trigger mob death tech
wormhole field needs a buff
it's good on wide open maps, but it needs a defensive effect on more closed maps
fix?
increase energy regen?
new tech?
a way to make more blocks
the block can feed into worms/coupling energy
tech: - remove the research costs of all tech
there's about 15 tech with a research cost
!!conformal - similar rules for small and big scales linked to holographic principle