affine connection

tech: affine connection - wormholes can now tunnel through the map at 200% increased energy cost
tech: regression - after bullets hit a mob, the mob takes 5% more future damage (0.5% for bosses)
tech: axion - while inside the MACHO halo, 75% of your total harm reduction is added as damage

mob: launcherOne - launches 1 big seeker bullet that chases you
black holes boss and final boss spawn big seeker bullets that chases you during the black hole phase

applied science no longer gives research (just a random tech for every gun you have)
bot fabrication increase cost every 5 -> x6 bots

average console time to disappear is 3 -> 4 seconds
ammo power ups no longer log ammo to in game console for performance reasons

JUNK tech: catabolysis - set max health to 1; double your current ammo 10 times (2^10 = 1024x ammo)
This commit is contained in:
landgreen
2021-11-28 05:28:01 -08:00
parent 677989dd02
commit f8b18c7772
11 changed files with 11005 additions and 10910 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
.DS_Store
.DS_Store
.DS_Store
js/workspace.code-workspace

View File

@@ -186,6 +186,7 @@ function collisionChecks(event) {
color: simulation.playerDmgColor,
time: simulation.drawTime
});
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.005 : 1.05
return;
}
//mob + body collisions
@@ -231,15 +232,15 @@ function collisionChecks(event) {
}
//determine if player is on the ground
Events.on(engine, "collisionStart", function(event) {
Events.on(engine, "collisionStart", function (event) {
playerOnGroundCheck(event);
// playerHeadCheck(event);
if (m.alive) collisionChecks(event);
});
Events.on(engine, "collisionActive", function(event) {
Events.on(engine, "collisionActive", function (event) {
playerOnGroundCheck(event);
// playerHeadCheck(event);
});
Events.on(engine, "collisionEnd", function(event) {
Events.on(engine, "collisionEnd", function (event) {
playerOffGroundCheck(event);
});

View File

@@ -16,18 +16,17 @@ const level = {
// localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.setField("molecular assembler")
// m.setField("wormhole")
// b.giveGuns("laser")
// b.giveGuns("nail gun")
// b.giveGuns("harpoon")
// tech.giveTech("darts")
// tech.giveTech("incendiary ammunition")
// tech.giveTech("affine connection")
// tech.giveTech("regression")
// tech.giveTech("relativistic momentum")
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
// tech.giveTech("antiscience")
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.isCancelDuplication = true
level.intro(); //starting level
// level.testing(); //not in rotation, used for testing
@@ -132,8 +131,8 @@ const level = {
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "tech", false); //start
}
},
custom() {},
customTopLayer() {},
custom() { },
customTopLayer() { },
setDifficulty() {
simulation.difficulty = 0
b.dmgScale = 1; //damage done by player decreases each level
@@ -575,7 +574,7 @@ const level = {
body[body.length] = rotor1
body[body.length] = rotor2
setTimeout(function() {
setTimeout(function () {
rotor.collisionFilter.category = cat.body;
rotor.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet //| cat.map
}, 1000);
@@ -590,7 +589,7 @@ const level = {
Composite.add(engine.world, constraint);
if (rotate) {
rotor.rotate = function() {
rotor.rotate = function () {
if (!m.isBodiesAsleep) {
Matter.Body.applyForce(rotor, {
x: rotor.position.x + 100,
@@ -793,7 +792,7 @@ const level = {
y: 0
}, angleB)
draw = function() {
draw = function () {
ctx.beginPath(); //portal
let v = this.vertices;
ctx.moveTo(v[0].x, v[0].y);
@@ -803,7 +802,7 @@ const level = {
ctx.fillStyle = this.color
ctx.fill();
}
query = function(isRemoveBlocks = false) {
query = function (isRemoveBlocks = false) {
if (Matter.Query.collides(this, [player]).length === 0) { //not touching player
if (player.isInPortal === this) player.isInPortal = null
} else if (player.isInPortal !== this) { //touching player
@@ -998,7 +997,7 @@ const level = {
opticalQuery() {
if (this.isOn) {
//draw
ctx.fillStyle = `hsla(0, 100%, 50%,${0.6+0.4*Math.random()})`
ctx.fillStyle = `hsla(0, 100%, 50%,${0.6 + 0.4 * Math.random()})`
ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
//collision with player
if (this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) {
@@ -1418,7 +1417,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
fireBlock = function(xPos, yPos) {
fireBlock = function (xPos, yPos) {
const index = body.length
spawn.bodyRect(xPos, yPos, 35 + 50 * Math.random(), 35 + 50 * Math.random());
const bodyBullet = body[body.length - 1]
@@ -1474,7 +1473,7 @@ const level = {
button.isReadyToFire = true
} else if (button.isReadyToFire && !button.isUp) {
button.isReadyToFire = false
fireBlock = function(xPos, yPos) {
fireBlock = function (xPos, yPos) {
const index = body.length
spawn.bodyRect(xPos, yPos, 35 + 50 * Math.random(), 35 + 50 * Math.random());
const bodyBullet = body[body.length - 1]
@@ -1569,7 +1568,7 @@ const level = {
y: -5
});
}
ctx.fillStyle = `rgba(255,0,255,${0.2+0.7*Math.random()})`
ctx.fillStyle = `rgba(255,0,255,${0.2 + 0.7 * Math.random()})`
ctx.fillRect(bounds.min.x, y - 185, 38, 70);
}
}
@@ -1636,7 +1635,7 @@ const level = {
y: -5
});
}
ctx.fillStyle = `rgba(255,0,255,${0.2+0.7*Math.random()})`
ctx.fillStyle = `rgba(255,0,255,${0.2 + 0.7 * Math.random()})`
ctx.fillRect(bounds.min.x, y - 185, 38, 70);
}
}
@@ -1888,7 +1887,7 @@ const level = {
Composite.add(engine.world, who); //add to world
}
let r = 150
let hexagon = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 ${r*Math.cos(2.0944)} ${r*Math.sin(2.0944)} ${r*Math.cos(1.0472)} ${r*Math.sin(1.0472)} `
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
//450 horizontal spread // -130-130-130 = 390 vertical
if (Math.random() < 0.5) {
spawn.mapVertex(x + 775, y + -260, hexagon);
@@ -1977,13 +1976,13 @@ const level = {
}
//right side hexagons
let r = 300
let hexagon = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 ${r*Math.cos(2.0944)} ${r*Math.sin(2.0944)} ${r*Math.cos(1.0472)} ${r*Math.sin(1.0472)} `
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
spawn.mapVertex(x + 1640, y + -365, hexagon);
// r = 275
// let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 `
// spawn.mapVertex(x + 2300, y + -75, hexagonHalf);
r = 150
const hexagon150 = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 ${r*Math.cos(2.0944)} ${r*Math.sin(2.0944)} ${r*Math.cos(1.0472)} ${r*Math.sin(1.0472)} `
const hexagon150 = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
// spawn.mapVertex(x + 1750, y + -550, hexagon150);
spawn.mapVertex(x + 1750, y + -1100, hexagon150);
spawn.mapVertex(x + 1750, y + -1650, hexagon150);
@@ -1991,7 +1990,7 @@ const level = {
//left side
r = 350
let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 `
let hexagonHalf = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 `
spawn.mapVertex(x + 425, y + -90, hexagonHalf);
spawn.mapVertex(x + 850, y + -500, hexagon150);
@@ -2338,10 +2337,10 @@ const level = {
spawn.mapRect(4850, -275, 50, 175);
//???
level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// spawn.starter(1900, -500, 200) //big boy
level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
spawn.starter(1900, -500, 200) //big boy
// spawn.spiderBoss(1700, -500)
// spawn.launcherOne(1700, -500)
// spawn.launcherBoss(3200, -500)
// spawn.laserTargetingBoss(1700, -500)
// spawn.powerUpBoss(3200, -500)
@@ -2371,7 +2370,7 @@ const level = {
// spawn.blinkBoss(1600, -500)
// spawn.laserTargetingBoss(1700, -120)
// spawn.bomberBoss(1400, -500)
spawn.laser(1800, -320)
// spawn.laser(1800, -320)
// spawn.laserBombingBoss(1600, -500)
// spawn.laserTargetingBoss(1600, -500)
// spawn.laserBoss(1600, -500)
@@ -2389,7 +2388,7 @@ const level = {
level.exit.draw();
level.enter.draw();
};
level.customTopLayer = () => {};
level.customTopLayer = () => { };
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 1500;
level.exit.y = -1875;
@@ -5519,7 +5518,7 @@ const level = {
if (mob[i].isBoss) me = mob[i]
}
if (me) {
me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs
me.onDeath = function () { //please don't edit the onDeath function this causes serious bugs
spawnCouloirEnHaut()
doorSortieSalle.isOpen = false;
};
@@ -5535,7 +5534,7 @@ const level = {
if (mob[i].isBoss) me = mob[i]
}
if (me) {
me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs
me.onDeath = function () { //please don't edit the onDeath function this causes serious bugs
spawnCouloirEnHaut()
doorSortieSalle.isOpen = false;
};
@@ -5760,11 +5759,11 @@ const level = {
body[body.length] = part4;
body[body.length] = part5;
body[body.length] = part6;
setTimeout(function() {
setTimeout(function () {
chair.collisionFilter.category = cat.body;
chair.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
setTimeout(function() {
setTimeout(function () {
chair2.collisionFilter.category = cat.body;
chair2.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
@@ -5819,7 +5818,7 @@ const level = {
body[body.length] = rightUpperLeg
body[body.length] = rightLowerArm
body[body.length] = rightUpperArm
setTimeout(function() {
setTimeout(function () {
person.collisionFilter.category = cat.body;
person.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);
@@ -6211,7 +6210,7 @@ const level = {
level.exit.draw();
level.enter.draw();
};
level.customTopLayer = () => {};
level.customTopLayer = () => { };
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
@@ -7270,7 +7269,7 @@ const level = {
body[body.length] = part1;
body[body.length] = part2;
body[body.length] = part3;
setTimeout(function() {
setTimeout(function () {
compoundParts.collisionFilter.category = cat.body;
compoundParts.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
}, 1000);

View File

@@ -11,7 +11,6 @@ const lore = {
} else if (simulation.difficultyMode === 6) {
this.techGoal = 1
}
},
talkingColor: "#dff", //set color of graphic on level.null
isSpeech: false,
@@ -42,6 +41,17 @@ const lore = {
lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
},
unlockTesting() {
if (localSettings.loreCount < 1) localSettings.loreCount = 1
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
simulation.makeTextLog(`<span class='color-var'>lore</span>.unlockTesting()`, Infinity);
sound.portamento(50)
sound.portamento(83.333)
sound.portamento(166.666)
},
anand: {
color: "#e0c",
voice: undefined,
@@ -490,19 +500,6 @@ const lore = {
// () => { lore.miriam.text("And that is why you keep running these fighting simulations.") },
// () => { lore.miriam.text("You haven't been researching new technology.") },
// () => { lore.miriam.text("You've are planning how to escape.") },
unlockTesting() {
if (localSettings.loreCount < 1) localSettings.loreCount = 1
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
simulation.makeTextLog(`<span class='color-var'>lore</span>.unlockTesting()`, Infinity);
sound.portamento(50)
sound.portamento(83.333)
sound.portamento(166.666)
},
}

View File

@@ -128,7 +128,7 @@ const mobs = {
const y = who.position.y - w * 0.7;
ctx.fillStyle = "rgba(100, 100, 100, 0.3)";
ctx.fillRect(x, y, w, h);
ctx.fillStyle = `rgba(${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},0.5)`
ctx.fillStyle = `rgba(${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},${Math.floor(255 * Math.random())},0.5)`
ctx.fillRect(x, y, w * who.health, h);
//draw fill inside mob
@@ -165,7 +165,7 @@ const mobs = {
});
}
},
endEffect() {},
endEffect() { },
dmg: tickDamage,
type: "dot",
endCycle: simulation.cycle + cycles,
@@ -472,7 +472,7 @@ const mobs = {
}
},
laser() {
const vertexCollision = function(v1, v1End, domain) {
const vertexCollision = function (v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -609,7 +609,7 @@ const mobs = {
ctx.fillStyle = "rgba(0,0,0,0.07)";
ctx.fill();
//spring to random place on map
const vertexCollision = function(v1, v1End, domain) {
const vertexCollision = function (v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -676,7 +676,7 @@ const mobs = {
},
curl(range = 1000, mag = -10) {
//cause all mobs, and bodies to rotate in a circle
applyCurl = function(center, array, isAntiGravity = true) {
applyCurl = function (center, array, isAntiGravity = true) {
for (let i = 0; i < array.length; ++i) {
if (!array[i].isNotHoldable) {
const sub = Vector.sub(center, array[i].position)
@@ -686,10 +686,17 @@ const mobs = {
if (radius2 < range * range && radius2 > 10000) {
const curlVector = Vector.mult(Vector.perp(Vector.normalise(sub)), mag)
//apply curl force
if (array[i].isMobBullet) {
Matter.Body.setVelocity(array[i], {
x: array[i].velocity.x * 0.97 + curlVector.x * 0.06,
y: array[i].velocity.y * 0.97 + curlVector.y * 0.06
})
} else {
Matter.Body.setVelocity(array[i], {
x: array[i].velocity.x * 0.94 + curlVector.x * 0.06,
y: array[i].velocity.y * 0.94 + curlVector.y * 0.06
})
}
if (isAntiGravity) array[i].force.y -= 0.8 * simulation.g * array[i].mass
// //draw curl, for debugging
// ctx.beginPath();
@@ -818,7 +825,7 @@ const mobs = {
//be sure to declare searchTarget in mob spawn
//accelerate towards the searchTarget
if (!this.seePlayer.recall) {
const newTarget = function(that) {
const newTarget = function (that) {
if (Math.random() < 0.0005) {
that.searchTarget = player.position; //chance to target player
} else {
@@ -1221,7 +1228,7 @@ const mobs = {
for (let i = 0, len = consBB.length; i < len; ++i) {
if (consBB[i].bodyA === this) {
if (consBB[i].bodyB.shield) {
consBB[i].bodyB.do = function() {
consBB[i].bodyB.do = function () {
this.death();
};
}
@@ -1231,7 +1238,7 @@ const mobs = {
break;
} else if (consBB[i].bodyB === this) {
if (consBB[i].bodyA.shield) {
consBB[i].bodyA.do = function() {
consBB[i].bodyA.do = function () {
this.death();
};
}
@@ -1290,7 +1297,7 @@ const mobs = {
//large mobs shrink so they don't block paths
if (body[len].mass + body[len2].mass > 16) {
const massLimit = 8 + 6 * Math.random()
const shrink = function(that1, that2) {
const shrink = function (that1, that2) {
if (that1.mass + that2.mass > massLimit) {
const scale = 0.95;
Matter.Body.scale(that1, scale, scale);
@@ -1313,7 +1320,7 @@ const mobs = {
//large mobs shrink so they don't block paths
if (body[len].mass > 9) {
const massLimit = 7 + 4 * Math.random()
const shrink = function(that) {
const shrink = function (that) {
if (that.mass > massLimit) {
const scale = 0.95;
Matter.Body.scale(that, scale, scale);

View File

@@ -57,7 +57,7 @@ const m = {
},
setFillColors() {
this.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light-25}%)`
this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%)`
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor);
@@ -183,7 +183,7 @@ const m = {
lastGroundedPositionY: 0,
// mouseZoom: 0,
lookSmoothing: 0.07, //1 is instant jerky, 0.001 is slow smooth zoom, 0.07 is standard
look() {}, //set to lookDefault()
look() { }, //set to lookDefault()
lookDefault() {
//always on mouse look
m.angle = Math.atan2(
@@ -405,7 +405,7 @@ const m = {
m.health = 1;
// m.addHealth(1)
simulation.wipe = function() { //set wipe to have trails
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
@@ -415,8 +415,8 @@ const m = {
m.switchWorlds()
const swapPeriod = 1000
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function() {
simulation.wipe = function() { //set wipe to have trails
setTimeout(function () {
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
@@ -424,16 +424,16 @@ const m = {
simulation.clearNow = true; //triggers a map reset
m.switchWorlds()
simulation.isTextLogOpen = true;
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len-i-1}`, swapPeriod);
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len - i - 1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i + 1) * (i + 1) * 0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}, (i + 1) * swapPeriod);
}
setTimeout(function() {
simulation.wipe = function() { //set wipe to normal
setTimeout(function () {
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
simulation.isTextLogOpen = true;
@@ -448,7 +448,7 @@ const m = {
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
document.getElementById("fade-out").style.opacity = 0.9; //slowly fade to 90% white on top of canvas
// build.shareURL(false)
setTimeout(function() {
setTimeout(function () {
Composite.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
@@ -491,7 +491,7 @@ const m = {
baseHealth: 1,
setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage //+ tech.bonusHealth
document.getElementById("health-bg").style.width = `${Math.floor(300*m.maxHealth)}px`
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
@@ -588,7 +588,7 @@ const m = {
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
let isDrawPlayer = true
const shortPause = function() {
const shortPause = function () {
if (m.defaultFPSCycle < m.cycle) { //back to default values
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
@@ -657,13 +657,13 @@ const m = {
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
m.energy = m.maxEnergy
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function() {
setTimeout(function () {
tech.maxDuplicationEvent()
simulation.wipe = function() { //set wipe to normal
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -686,13 +686,13 @@ const m = {
<br>${powerUps.research.count}`)
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails
simulation.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function() {
setTimeout(function () {
tech.maxDuplicationEvent()
simulation.wipe = function() { //set wipe to normal
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -709,7 +709,7 @@ const m = {
}
if (dmg > 0.06 / m.holdingMassScale) m.drop(); //drop block if holding
const normalFPS = function() {
const normalFPS = function () {
if (m.defaultFPSCycle < m.cycle) { //back to default values
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
@@ -808,38 +808,7 @@ const m = {
m.knee.x = (l / d) * (m.foot.x - m.hip.x) - (h / d) * (m.foot.y - m.hip.y) + m.hip.x + offset;
m.knee.y = (l / d) * (m.foot.y - m.hip.y) + (h / d) * (m.foot.x - m.hip.x) + m.hip.y;
},
draw() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
//draw body
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient;
ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
// draw eye; used in flip-flop
// ctx.beginPath();
// ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
// ctx.fillStyle = m.eyeFillColor;
// ctx.fill()
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
},
draw() { },
drawFlipFlop() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -875,17 +844,13 @@ const m = {
drawDefault() {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
//draw body
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
@@ -895,12 +860,6 @@ const m = {
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
// draw eye; used in flip-flop
// ctx.beginPath();
// ctx.arc(15, 0, 3.5, 0, 2 * Math.PI);
// ctx.fillStyle = m.eyeFillColor;
// ctx.fill()
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
},
@@ -1022,7 +981,7 @@ const m = {
ctx.fillRect(xOff, yOff, range * m.energy, 10);
}
},
drawFieldMeterCloaking: function() {
drawFieldMeterCloaking: function () {
if (m.energy < m.maxEnergy) { // replaces m.drawFieldMeter() with custom code
m.regenEnergy();
const xOff = m.pos.x - m.radius * m.maxEnergy
@@ -1038,11 +997,11 @@ const m = {
ctx.stroke();
}
},
regenEnergy: function() { //used in drawFieldMeter // rewritten by some tech
regenEnergy: function () { //used in drawFieldMeter // rewritten by some tech
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0
},
regenEnergyDefault: function() {
regenEnergyDefault: function () {
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0
},
@@ -1230,7 +1189,7 @@ const m = {
m.holdingTarget.friction = m.holdingTarget.frictionStatic = m.holdingTarget.frictionAir = 0.001
}
//check every second to see if player is away from thrown body, and make solid
const solid = function(that) {
const solid = function (that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) {
@@ -1262,7 +1221,7 @@ const m = {
m.definePlayerMass() //return to normal player mass
if (tech.isAddBlockMass) {
const expand = function(that, massLimit) {
const expand = function (that, massLimit) {
if (that.mass < massLimit) {
const scale = 1.05;
Matter.Body.scale(that, scale, scale);
@@ -1507,7 +1466,7 @@ const m = {
// wake(powerUp);
}
},
hold() {},
hold() { },
setField(index) {
if (isNaN(index)) { //find index by name
let found = false
@@ -1531,7 +1490,7 @@ const m = {
description: "regen <strong>6</strong> <strong class='color-f'>energy</strong> per second<br>use it to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong><br><strong class='color-f'>energy</strong> regen disabled if immune to <strong class='color-harm'>harm</strong>",
// description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> <strong class='color-block'>blocks</strong><br>regen <strong>6</strong> <strong class='color-f'>energy</strong>/s, when not immune to <strong class='color-harm'>harm</strong>",
effect: () => {
m.hold = function() {
m.hold = function () {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -1625,7 +1584,7 @@ const m = {
} else {
m.harmonicShield = m.harmonicAtomic
}
m.hold = function() {
m.hold = function () {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -1758,7 +1717,7 @@ const m = {
}
}
}
m.hold = function() {
m.hold = function () {
const wave = Math.sin(m.cycle * 0.022);
m.fieldRange = 160 + 12 * wave + 100 * tech.isBigField
m.fieldArc = 0.34 + 0.04 * wave + 0.065 * tech.isBigField //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
@@ -1850,7 +1809,7 @@ const m = {
m.fieldHarmReduction = 0.45; //55% reduction
m.fieldDrawRadius = 0;
m.hold = function() {
m.hold = function () {
m.airSpeedLimit = 125 //5 * player.mass * player.mass
m.FxAir = 0.016
if (m.isHolding) {
@@ -1994,7 +1953,7 @@ const m = {
effect: () => {
// m.fieldMeterColor = "#0c5"
// m.eyeFillColor = m.fieldMeterColor
m.hold = function() {
m.hold = function () {
if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) {
if (tech.isSporeField) {
if (tech.isSporeWorm) {
@@ -2115,7 +2074,7 @@ const m = {
set() {
b.isExtruderOn = false
if (tech.isExtruder) {
m.hold = function() {
m.hold = function () {
b.isExtruderOn = false
if (m.isHolding) {
m.drawHold(m.holdingTarget);
@@ -2156,7 +2115,7 @@ const m = {
ctx.stroke();
}
} else {
m.hold = function() {
m.hold = function () {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2188,7 +2147,7 @@ const m = {
if (tech.isRewindField) {
this.rewindCount = 0
m.grabPowerUpRange2 = 300000
m.hold = function() {
m.hold = function () {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
m.holding();
@@ -2358,7 +2317,7 @@ const m = {
m.fieldFire = true;
m.isBodiesAsleep = false;
m.drain = 0.0005
m.hold = function() {
m.hold = function () {
if (m.isHolding) {
m.wakeCheck();
m.drawHold(m.holdingTarget);
@@ -2454,7 +2413,7 @@ const m = {
m.isSneakAttack = true;
const drawRadius = 900
m.hold = function() {
m.hold = function () {
// console.log(m.holdingTarget)
if (m.isHolding) {
m.drawHold(m.holdingTarget);
@@ -2717,7 +2676,7 @@ const m = {
m.fieldOn = false;
m.fieldRadius = 0;
m.drop();
m.hold = function() {
m.hold = function () {
if (input.field) {
if (m.fieldCDcycle < m.cycle) {
const scale = 25
@@ -2897,12 +2856,13 @@ const m = {
{
name: "wormhole",
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
effect: function() {
drain: 0,
effect: function () {
m.duplicateChance = 0.07
m.fieldRange = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
m.hold = function() {
m.hold = function () {
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference
// isOn: false,
// isReady: true,
@@ -3098,12 +3058,15 @@ const m = {
const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos)), 50), simulation.mouseInGame)
const sub = Vector.sub(simulation.mouseInGame, m.pos)
const mag = Vector.magnitude(sub)
const drain = tech.isFreeWormHole ? 0 : 0.06 + 0.006 * Math.sqrt(mag)
if (input.field) {
m.grabPowerUp();
//draw possible wormhole
if (mag > 250 && m.energy > drain) {
if (tech.isWormholeMapIgnore && Matter.Query.ray(map, m.pos, justPastMouse).length !== 0) {
this.drain = (0.06 + 0.006 * Math.sqrt(mag)) * 2
} else {
this.drain = tech.isFreeWormHole ? 0 : 0.06 + 0.006 * Math.sqrt(mag)
}
const unit = Vector.perp(Vector.normalise(sub))
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
m.fieldRange = 0.97 * m.fieldRange + 0.03 * (50 + 10 * Math.sin(simulation.cycle * 0.025))
@@ -3115,6 +3078,8 @@ const m = {
ctx.moveTo(where.x, where.y)
ctx.bezierCurveTo(where.x, where.y, simulation.mouseInGame.x, simulation.mouseInGame.y, edge2b.x, edge2b.y);
if (
mag > 250 && m.energy > this.drain &&
(tech.isWormholeMapIgnore || Matter.Query.ray(map, m.pos, justPastMouse).length === 0) &&
Matter.Query.region(map, {
min: {
x: simulation.mouseInGame.x - scale,
@@ -3124,8 +3089,7 @@ const m = {
x: simulation.mouseInGame.x + scale,
y: simulation.mouseInGame.y + scale
}
}).length === 0 &&
Matter.Query.ray(map, m.pos, justPastMouse).length === 0
}).length === 0
) {
m.hole.isReady = true;
// ctx.fillStyle = "rgba(255,255,255,0.5)"
@@ -3142,13 +3106,11 @@ const m = {
ctx.stroke();
ctx.setLineDash([]);
}
} else {
m.hole.isReady = false;
}
} else {
//make new wormhole
if (
m.hole.isReady && mag > 250 && m.energy > drain &&
m.hole.isReady && mag > 250 && m.energy > this.drain &&
(tech.isWormholeMapIgnore || Matter.Query.ray(map, m.pos, justPastMouse).length === 0) &&
Matter.Query.region(map, {
min: {
x: simulation.mouseInGame.x - scale,
@@ -3158,10 +3120,9 @@ const m = {
x: simulation.mouseInGame.x + scale,
y: simulation.mouseInGame.y + scale
}
}).length === 0 &&
Matter.Query.ray(map, m.pos, justPastMouse).length === 0
}).length === 0
) {
m.energy -= drain
m.energy -= this.drain
m.hole.isReady = false;
m.fieldRange = 0
Matter.Body.setPosition(player, simulation.mouseInGame);
@@ -3207,7 +3168,6 @@ const m = {
}
}
}
// if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
// const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos)), 50), simulation.mouseInGame)
// const scale = 60

View File

@@ -321,7 +321,7 @@ const powerUps = {
}
if (tech.isRerollBots) {
let delay = 0
for (const cost = 2 + Math.floor(0.2 * b.totalBots()); powerUps.research.count > cost - 1; powerUps.research.count -= cost) {
for (const cost = 2 + Math.floor(0.1666 * b.totalBots()); powerUps.research.count > cost - 1; powerUps.research.count -= cost) {
delay += 500
setTimeout(() => {
b.randomBot()
@@ -469,30 +469,30 @@ const powerUps = {
if (tech.ammoCap) {
const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap) //0.7 is average
target.ammo = ammoAdded
simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}`)
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}`)
} else {
const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack)
target.ammo += ammoAdded
simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`)
// simulation.makeTextLog(`${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`)
}
}
} else { //give ammo to all guns in inventory
let textLog = ""
// let textLog = ""
for (let i = 0, len = b.inventory.length; i < len; i++) {
const target = b.guns[b.inventory[i]]
if (target.ammo !== Infinity) {
if (tech.ammoCap) {
const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average
target.ammo = ammoAdded
textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}<br>`
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>=</span> ${ammoAdded}<br>`
} else {
const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack)
target.ammo += ammoAdded
textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}<br>`
// textLog += `${target.name}.<span class='color-g'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}<br>`
}
}
}
simulation.makeTextLog(textLog)
// simulation.makeTextLog(textLog)
}
// } else { //give ammo to all guns in inventory
// for (let i = 0, len = b.inventory.length; i < len; i++) {

View File

@@ -354,7 +354,7 @@ const simulation = {
// <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#7ce" stroke="none" /> -->
// SVGleftMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#149" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
// SVGrightMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#0cf" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
makeTextLog(text, time = 180) {
makeTextLog(text, time = 240) {
if (simulation.isTextLogOpen && !build.isExperimentSelection) {
if (simulation.lastLogTime > m.cycle) { //if there is an older message
document.getElementById("text-log").innerHTML = document.getElementById("text-log").innerHTML + '<br>' + text;

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
const tech = {
const tech = {
totalCount: null,
setupAllTech() {
for (let i = 0, len = tech.tech.length; i < len; i++) {
@@ -209,6 +209,7 @@
},
damageFromTech() {
let dmg = 1 //m.fieldDamage
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
if (tech.OccamDamage) dmg *= tech.OccamDamage
if (tech.isCloakingDamage) dmg *= 1.35
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.5
@@ -314,7 +315,7 @@
name: "entanglement",
nameInfo: "<span id = 'tech-entanglement'></span>",
addNameInfo() {
setTimeout(function() {
setTimeout(function () {
simulation.boldActiveGunHUD();
}, 1000);
},
@@ -329,7 +330,7 @@
requires: "at least 2 guns, not mass-energy",
effect() {
tech.isEntanglement = true
setTimeout(function() {
setTimeout(function () {
simulation.boldActiveGunHUD();
}, 1000);
@@ -424,7 +425,7 @@
if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
}
},
remove() {}
remove() { }
},
{
name: "ad hoc",
@@ -453,11 +454,11 @@
}
}
},
remove() {}
remove() { }
},
{
name: "applied science",
description: `spawn ${powerUps.orb.research(1)} and get a random <strong class='color-m'>tech</strong><br>for each <strong class='color-g'>gun</strong> in your inventory`,
description: `get a random <strong class='color-m'>tech</strong><br>for each <strong class='color-g'>gun</strong> in your inventory`, //spawn ${powerUps.orb.research(1)} and
maxCount: 9,
count: 0,
isNonRefundable: true,
@@ -470,7 +471,7 @@
effect() {
for (let i = b.inventory.length - 1; i > -1; i--) {
//spawn a research for each gun
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
//find a gun tech for this gun
const gunTechPool = []
for (let j = 0, len = tech.tech.length; j < len; j++) {
@@ -496,7 +497,7 @@
}
simulation.boldActiveGunHUD();
},
remove() {}
remove() { }
},
{
name: "logistics",
@@ -519,7 +520,7 @@
{
name: "supply chain",
junk: 0.05,
descriptionFunction() { return `double your current <strong class='color-ammo'>ammo</strong> for all <strong class='color-g'>guns</strong><br><strong>+${this.junk*100}%</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool` },
descriptionFunction() { return `double your current <strong class='color-ammo'>ammo</strong> for all <strong class='color-g'>guns</strong><br><strong>+${this.junk * 100}%</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool` },
maxCount: 9,
count: 0,
frequency: 1,
@@ -732,6 +733,23 @@
tech.isFarAwayDmg = false;
}
},
{
name: "regression",
description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>5%</strong> for mobs <em>(0.5% for bosses)</em>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() { return true },
requires: "",
effect() {
tech.isLessDamageReduction = true
},
remove() {
tech.isLessDamageReduction = false
}
},
{
name: "simulated annealing",
description: "increase <strong class='color-d'>damage</strong> by <strong>20%</strong><br><strong>20%</strong> increased <strong><em>delay</em></strong> after firing",
@@ -1539,7 +1557,7 @@
name: "bot fabrication",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">bot fabrication</a>`,
descriptionFunction() {
return `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`
return `after you collect ${powerUps.orb.research(2 + Math.floor(0.1666 * b.totalBots()))}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 6 bots)</em>`
},
// description: `if you collect ${powerUps.orb.research(2)}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`,
maxCount: 1,
@@ -1691,7 +1709,7 @@
{
name: "capacitor bank",
// description: "<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, foam, railgun, pulse, tokamak</em>",
descriptionFunction() { return `<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, ${tech.haveGunCheck("foam", false)?"<strong>foam</strong>" :"foam"}, ${tech.isRailGun?"<strong>railgun</strong>" :"railgun"}, ${tech.isPulseLaser?"<strong>pulse</strong>" :"pulse"}, ${tech.isTokamak?"<strong>tokamak</strong>" :"tokamak"}</em>` },
descriptionFunction() { return `<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, ${tech.haveGunCheck("foam", false) ? "<strong>foam</strong>" : "foam"}, ${tech.isRailGun ? "<strong>railgun</strong>" : "railgun"}, ${tech.isPulseLaser ? "<strong>pulse</strong>" : "pulse"}, ${tech.isTokamak ? "<strong>tokamak</strong>" : "tokamak"}</em>` },
maxCount: 1,
count: 0,
frequency: 2,
@@ -1893,7 +1911,7 @@
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after a <strong>collision</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
nameInfo: "<span id = 'tech-flip-flop'></span>",
addNameInfo() {
setTimeout(function() {
setTimeout(function () {
if (document.getElementById("tech-flip-flop")) {
if (tech.isFlipFlopOn) {
document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
@@ -1931,7 +1949,7 @@
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after picking up a <strong>power up</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
nameInfo: "<span id = 'tech-switch'></span>",
addNameInfo() {
setTimeout(function() {
setTimeout(function () {
if (document.getElementById("tech-switch")) {
if (tech.isFlipFlopOn) {
document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
@@ -2182,6 +2200,24 @@
}
}
},
{
name: "axion",
description: "while inside the <strong>MACHO</strong> <strong>75%</strong> of your total<br><strong class='color-harm'>harm</strong> reduction is added to your <strong class='color-d'>damage</strong>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isMACHO
},
requires: "MACHO",
effect: () => {
tech.isAxion = true
},
remove() {
tech.isAxion = false
}
},
{
name: "ablative drones",
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
@@ -2580,7 +2616,7 @@
requires: "not ground state, apex predator",
effect() {
tech.isCrouchRegen = true; //only used to check for requirements
m.regenEnergy = function() {
m.regenEnergy = function () {
if (m.immuneCycle < m.cycle && m.crouch) m.energy += 7 * m.fieldRegen; //m.fieldRegen = 0.001
if (m.energy < 0) m.energy = 0
}
@@ -2652,7 +2688,7 @@
requires: "not inductive coupling",
effect() {
tech.isDamageAfterKillNoRegen = true;
m.regenEnergy = function() {
m.regenEnergy = function () {
if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle)) m.energy += m.fieldRegen; //m.fieldRegen = 0.001
if (m.energy < 0) m.energy = 0
}
@@ -2870,13 +2906,13 @@
if (tech.tech[i].isHealTech) tech.tech[i].frequency *= 2
}
},
remove() {}
remove() { }
},
{
name: "anthropic principle",
nameInfo: "<span id = 'tech-anthropic'></span>",
addNameInfo() {
setTimeout(function() {
setTimeout(function () {
powerUps.research.changeRerolls(0)
}, 1000);
},
@@ -2893,7 +2929,7 @@
effect() {
tech.isDeathAvoid = true;
tech.isDeathAvoidedThisLevel = false;
setTimeout(function() {
setTimeout(function () {
powerUps.research.changeRerolls(0)
}, 1000);
},
@@ -3149,12 +3185,12 @@
for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups
//have state is checked in m.death()
},
remove() {}
remove() { }
},
{
name: "Occam's razor",
descriptionFunction() {
return `randomly remove <strong>${this.removePercent*100}%</strong> of your <strong class='color-m'>tech</strong><br>for each removed gain <strong>${this.damagePerRemoved*100}%</strong> <strong class='color-d'>damage</strong>`
return `randomly remove <strong>${this.removePercent * 100}%</strong> of your <strong class='color-m'>tech</strong><br>for each removed gain <strong>${this.damagePerRemoved * 100}%</strong> <strong class='color-d'>damage</strong>`
},
maxCount: 1,
count: 0,
@@ -3424,7 +3460,7 @@
tech.tech[choose].isLost = true
simulation.updateTechHUD();
},
remove() {}
remove() { }
},
{
name: "monte carlo experiment",
@@ -3443,7 +3479,7 @@
const removeTotal = tech.removeTech()
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
},
remove() {}
remove() { }
},
{
name: "strange attractor",
@@ -3464,7 +3500,7 @@
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (Math.random() < tech.duplicationChance() * 2) powerUps.directSpawn(m.pos.x + 10, m.pos.y + 5, "tech");
},
remove() {}
remove() { }
},
{
name: "vector fields",
@@ -3541,7 +3577,7 @@
}
}
},
remove() {}
remove() { }
},
{
name: "unified field theory",
@@ -5996,7 +6032,7 @@
b.randomBot()
b.randomBot()
},
remove() {}
remove() { }
},
{
name: "bot prototypes",
@@ -6073,7 +6109,7 @@
}
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it
},
remove() {}
remove() { }
},
{
name: "mycelium manufacturing",
@@ -6700,7 +6736,7 @@
},
{
name: "virtual particles",
description: `use ${powerUps.orb.research(4)}to exploit your <strong>wormhole</strong> for a<br><strong>13%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
description: `use ${powerUps.orb.research(4)}to exploit your <strong class='color-worm'>wormhole</strong> for a<br><strong>13%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -6793,16 +6829,16 @@
},
{
name: "charmed baryons",
description: `<strong>wormhole</strong> field uses no <strong class='color-f'>energy</strong><br><strong>move</strong> and <strong>jump</strong> <strong>33%</strong> <strong>slower</strong>`,
description: `<strong class='color-worm'>wormholes</strong> require <strong>zero</strong> <strong class='color-f'>energy</strong><br><strong>move</strong> and <strong>jump</strong> <strong>33%</strong> <strong>slower</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "wormhole"
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isWormholeMapIgnore
},
requires: "wormhole",
requires: "wormhole, not affine connection",
effect() {
tech.isFreeWormHole = true
tech.baseFx *= 0.66
@@ -6819,6 +6855,25 @@
}
}
},
{
name: "affine connection",
description: "<strong class='color-worm'>wormholes</strong> can tunnel through the <strong>map</strong><br>at <strong>200%</strong> increased <strong class='color-f'>energy</strong> cost",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isFreeWormHole
},
requires: "wormhole, not charmed baryons",
effect() {
tech.isWormholeMapIgnore = true
},
remove() {
tech.isWormholeMapIgnore = false
}
},
//**************************************************
//************************************************** experimental
//************************************************** modes
@@ -6839,7 +6894,7 @@
effect() {
m.shipMode()
},
remove() {}
remove() { }
},
{
name: "-quantum leap-",
@@ -7046,6 +7101,25 @@
// },
// remove() {}
// },
{
name: "catabolysis",
description: `set your <strong>maximum</strong> <strong class='color-h'>health</strong> to <strong>1</strong><br><strong>double</strong> your current <strong class='color-ammo'>ammo</strong> <strong>10</strong> times`,
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isExperimentHide: true,
isJunk: true,
allowed() { return !tech.isFallingDamage && !tech.isOverHeal && !tech.isEnergyHealth },
requires: "not quenching, tungsten carbide, mass-energy",
effect() {
m.baseHealth = 0.01
m.setMaxHealth();
for (let i = 0; i < b.guns.length; i++) b.guns[i].ammo = b.guns[i].ammo * Math.pow(2, 10)
simulation.updateGunHUD();
},
remove() { }
},
{
name: "density",
description: `<strong class='color-block'>block</strong> are <strong>100</strong> times less <strong>dense</strong>`,
@@ -7163,7 +7237,7 @@
const bc = new BroadcastChannel('planetesimals');
bc.activated = false
bc.onmessage = function(ev) {
bc.onmessage = function (ev) {
if (ev.data === 'tech') powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') {
m.death()
@@ -7175,7 +7249,7 @@
}
}
},
remove() {}
remove() { }
},
{
name: "facsimile",
@@ -7191,7 +7265,7 @@
effect() {
level.levels.splice(level.onLevel, 0, level.levels[level.onLevel]);
},
remove() {}
remove() { }
},
{
name: "negative friction",
@@ -7420,7 +7494,7 @@
effect: () => {
//setup audio context
function tone(frequency) {
const audioCtx = new(window.AudioContext || window.webkitAudioContext)();
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator1 = audioCtx.createOscillator();
const gainNode1 = audioCtx.createGain();
gainNode1.gain.value = 0.5; //controls volume
@@ -7434,7 +7508,7 @@
// let sound = tone(1050)
function EBS() {
const audioCtx = new(window.AudioContext || window.webkitAudioContext)();
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator1 = audioCtx.createOscillator();
const gainNode1 = audioCtx.createGain();
@@ -7499,7 +7573,7 @@
}, delay);
}, delay);
},
remove() {}
remove() { }
},
{
name: "automatic",
@@ -7542,7 +7616,7 @@
document.getElementById("health-bg").style.display = "none"
for (let i = 0; i < 15; i++) powerUps.spawn(m.pos.x + 160 * (Math.random() - 0.5), m.pos.y + 160 * (Math.random() - 0.5), "heal");
},
remove() {}
remove() { }
},
{
name: "not a bug",
@@ -7567,7 +7641,7 @@
// for (;;) {} //freezes the tab
},
remove() {}
remove() { }
},
{
name: "posture",
@@ -7607,7 +7681,7 @@
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand
}, 100);
},
remove() {}
remove() { }
},
{
name: "spinor",
@@ -7623,7 +7697,7 @@
},
requires: "",
effect() {
m.look = function() {
m.look = function () {
//always on mouse look
m.angle = (((m.pos.x + m.pos.y) / 100 + Math.PI) % Math.PI * 2) - Math.PI
//smoothed mouse look translations
@@ -7680,7 +7754,7 @@
}
}, 1000); //every 1 seconds
},
remove() {}
remove() { }
},
// {
// name: "inverted mouse",
@@ -7751,7 +7825,7 @@
simulation.makeGunHUD()
powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun");
},
remove() {}
remove() { }
},
{
name: "probability",
@@ -7781,7 +7855,7 @@
tech.tech[index].frequency = 100
}
},
remove() {}
remove() { }
},
{
name: "encryption",
@@ -7795,7 +7869,7 @@
allowed() { return true },
requires: "",
effect() {
String.prototype.shuffle = function() {
String.prototype.shuffle = function () {
var a = this.split(""),
n = a.length;
@@ -7810,7 +7884,7 @@
for (let i = 0, len = tech.tech.length; i < len; i++) tech.tech[i].name = tech.tech[i].name.shuffle()
},
remove() {}
remove() { }
},
{
name: "transparency",
@@ -7824,9 +7898,9 @@
allowed() { return true },
requires: "",
effect() {
m.draw = () => {}
m.draw = () => { }
},
remove() {}
remove() { }
},
{
name: "quantum leap",
@@ -7845,7 +7919,7 @@
simulation.trails()
}, 20000); //every 30 seconds
},
remove() {}
remove() { }
},
{
name: "score",
@@ -7864,7 +7938,7 @@
simulation.makeTextLog(`simulation.score <span class='color-symbol'>=</span> ${score.toFixed(0)}`);
}, 10000); //every 10 seconds
},
remove() {}
remove() { }
},
{
name: "pop-ups",
@@ -7882,7 +7956,7 @@
alert(`The best combo is ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name} with ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}!`);
}, 30000); //every 30 seconds
},
remove() {}
remove() { }
},
{
name: "music",
@@ -7898,7 +7972,7 @@
effect() {
window.open('https://www.youtube.com/results?search_query=music', '_blank')
},
remove() {}
remove() { }
},
{
name: "performance",
@@ -7912,9 +7986,9 @@
allowed() { return true },
requires: "",
effect() {
(function() {
(function () {
var script = document.createElement('script');
script.onload = function() {
script.onload = function () {
var stats = new Stats();
document.body.appendChild(stats.dom);
requestAnimationFrame(function loop() {
@@ -7929,7 +8003,7 @@
document.getElementById("health").style.left = "86px"
document.getElementById("health-bg").style.left = "86px"
},
remove() {}
remove() { }
},
{
name: "repartitioning",
@@ -7952,7 +8026,7 @@
}
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech");
},
remove() {}
remove() { }
},
{
name: "defragment",
@@ -7970,7 +8044,7 @@
if (tech.tech[i].isJunk) tech.tech[i].frequency = 0
}
},
remove() {}
remove() { }
},
{
name: "ship",
@@ -7989,7 +8063,7 @@
m.shipMode()
level.difficultyDecrease(simulation.difficultyMode)
},
remove() {}
remove() { }
},
// {
// name: "lubrication",
@@ -8026,7 +8100,7 @@
effect() {
setInterval(() => { if (!simulation.paused) ctx.rotate(0.001 * Math.sin(simulation.cycle * 0.01)) }, 16);
},
remove() {}
remove() { }
},
{
name: "umbra",
@@ -8043,7 +8117,7 @@
ctx.shadowColor = '#06f';
ctx.shadowBlur = 25;
},
remove() {}
remove() { }
},
{
name: "lighter",
@@ -8061,7 +8135,7 @@
effect() {
ctx.globalCompositeOperation = "lighter";
},
remove() {}
remove() { }
},
{
name: "rewind",
@@ -8079,7 +8153,7 @@
setTimeout(() => { m.rewind(120) }, i * 5000);
}
},
remove() {}
remove() { }
},
{
name: "energy to mass conversion",
@@ -8107,7 +8181,7 @@
}
},
remove() {}
remove() { }
},
{
name: "level.nextLevel()",
@@ -8123,7 +8197,7 @@
effect() {
level.nextLevel();
},
remove() {}
remove() { }
},
{
name: "expert system",
@@ -8140,7 +8214,7 @@
powerUps.spawn(m.pos.x, m.pos.y, "tech");
tech.addJunkTechToPool(0.64)
},
remove() {}
remove() { }
},
{
name: "energy investment",
@@ -8164,7 +8238,7 @@
}, i * 10000);
}
},
remove() {}
remove() { }
},
{
name: "missile Launching System",
@@ -8188,7 +8262,7 @@
}, i * 1000);
}
},
remove() {}
remove() { }
},
{
name: "grenade production",
@@ -8213,7 +8287,7 @@
}, i * 1000);
}
},
remove() {}
remove() { }
},
// {
// name: "inverted input",
@@ -8253,7 +8327,7 @@
},
requires: "",
effect() {
m.draw = function() {
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -8283,7 +8357,7 @@
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
},
remove() {}
remove() { }
},
{
name: "diegesis",
@@ -8299,7 +8373,7 @@
},
requires: "",
effect() {
m.draw = function() {
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -8324,7 +8398,7 @@
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
}
},
remove() {}
remove() { }
},
{
name: "pareidolia",
@@ -8340,7 +8414,7 @@
},
requires: "",
effect() {
m.draw = function() {
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
@@ -8393,7 +8467,7 @@
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15;
}
},
remove() {}
remove() { }
},
{
name: "prism",
@@ -8412,12 +8486,12 @@
sat: 100,
light: 50
}
setInterval(function() {
setInterval(function () {
m.color.hue++
m.setFillColors()
}, 10);
},
remove() {}
remove() { }
},
{
name: "assimilation",
@@ -8476,7 +8550,7 @@
const index = Math.floor(Math.random() * bots.length)
for (let i = 0; i < total; i++) bots[index]()
},
remove() {}
remove() { }
},
{
name: "growth hacking",
@@ -8492,7 +8566,7 @@
effect() {
level.difficultyIncrease(simulation.difficultyMode)
},
remove() {}
remove() { }
},
{
name: "stun",
@@ -8508,7 +8582,7 @@
effect() {
for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 480)
},
remove() {}
remove() { }
},
{
name: "re-arm",
@@ -8536,7 +8610,7 @@
}
simulation.makeGunHUD(); //update gun HUD
},
remove() {}
remove() { }
},
{
name: "re-research",
@@ -8558,7 +8632,7 @@
}
powerUps.research.count = 0
},
remove() {}
remove() { }
},
{
name: "quantum black hole",
@@ -8579,7 +8653,7 @@
powerUps.research.changeRerolls(-4)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>--</span><br>${powerUps.research.count}`)
},
remove() {}
remove() { }
},
{
name: "black hole cluster",
@@ -8599,7 +8673,7 @@
spawn.sucker(where.x, where.y)
}
},
remove() {}
remove() { }
},
//**************************************************
//************************************************** undefined / lore
@@ -8631,7 +8705,7 @@
// if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech[i].description = `${lore.techCount+1}/${lore.techGoal}<br><em>add copies of <strong class="lore-text">this</strong> to the potential <strong class='color-m'>tech</strong> pool</em>`
// }
// for (let i = 0, len = 10; i < len; i++) tech.addLoreTechToPool()
this.description = `<em>uncaught error:</em><br><strong>${Math.max(0,lore.techGoal-lore.techCount)}</strong> more required for access to <strong class="lore-text">null</strong>`
this.description = `<em>uncaught error:</em><br><strong>${Math.max(0, lore.techGoal - lore.techCount)}</strong> more required for access to <strong class="lore-text">null</strong>`
}
}, 1);
},
@@ -8960,4 +9034,7 @@
isCrouchRegen: null,
isDarts: null,
OccamDamage: null,
}
isAxion: null,
isWormholeMapIgnore: null,
isLessDamageReduction: null
}

View File

@@ -1,50 +1,46 @@
******************************************************** NEXT PATCH **************************************************
change: torpor - if you have NOT killed a mob in the last 5 seconds reduce harm by 66% (no negative effect though)
tech: affine connection - wormholes can now tunnel through the map at 200% increased energy cost
tech: regression - after bullets hit a mob, the mob takes 5% more future damage (0.5% for bosses)
tech: axion - while inside the MACHO halo, 75% of your total harm reduction is added as damage
mob: launcherOne - launches 1 big seeker bullet that chases you
black holes boss and final boss spawn big seeker bullets that chases you during the black hole phase
applied science no longer gives research (just a random tech for every gun you have)
bot fabrication increase cost every 5 -> x6 bots
average console time to disappear is 3 -> 4 seconds
ammo power ups no longer log ammo to in game console for performance reasons
JUNK tech: catabolysis - set max health to 1; double your current ammo 10 times (2^10 = 1024x ammo)
******************************************************** TODO ********************************************************
reduce some common in game console triggers, but lengthen default console time
don't log ammo?
don't log health
cap length of console?
new late game level that is easier if you can: platform well, jump high, immune to slime, wormhole through walls, fly fast
climb vertically to avoid rising slime
tech if you are inside the MACHO halo get a benefit
field tech - disable blocking, but does high damage to mobs inside field
and maybe slows mobs it damages
mob/boss that fires a laser at player, but give player time to avoid
laser isn't always on
they target where player was 1 second ago
they turn to face player?
dart: a new bullet type for string-less harpoons
can turn harder
dart, draw quick line to indicate targeting
can get new targets?
convert tech descriptions into a method()
this means the text would generate when you: press pause, or display options, or open experiment mode
this would allow the description to reference variables inside it, like this.count
who could use this:
Occam's razor
tech: dart - alt fire several small harpoons, with guidance
requires not railgun
tech: after bullets hit a mob, the mob takes 1% more damage
this.damageReduction *= 1.01
only for drones?
only for drones, spores, worms, ice-IX?
make it easier to push blocks around with your body
part of negative mass?
link to other block tech
tech: instead of throwing a block, give bots that last for 20 seconds
tech: open a new tab for n-gon, spawn things in the original game based on events in new game
if you die in new die in original?
new is n-gon classic?
make a JUNK tech?
if you die in original open a tab with a new n-gon that starts on a random level with a random load out. if you clear the level you come back to life in the original?
tech or field aspect - Firing now doesn't alert any mob but the mob you hit
bug - death while paused crashes game?
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
@@ -448,7 +444,6 @@ level boss: fires a line intersection in a random direction every few seconds.
******************************************************** LORE ********************************************************
possible names for tech
astrophage
strange loop
homeostasis
holonomy - parallel transport of a vector leads to movement (applies to curved space)
@@ -461,7 +456,6 @@ possible names for tech
Gödel's incompleteness
quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields)
counterfactual - something false
axion - maybe a 3rd dark matter type tech
Pigeonhole principle - if there are several things that are matched up
regression to the mean
phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston
@@ -469,13 +463,13 @@ possible names for tech
evolutionary cosmology
eternal inflation
hypergraph
gnarl
SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions.
nuclear pasta - hard matter in neutron star
nonlocal
fine-tuned universe
eternalism https://en.wikipedia.org/wiki/Eternalism_(philosophy_of_time)
axial motor
hall effect thrusters
a tutorial / lore intro
needs to be optional so it doesn't slow experienced players