substructure

new level substructure
  featured element - motion triggered lasers

futures exchange 5->6% duplication per cancel
plasma torch coupling 0.015->0.025x damage per coupling
Gibbs free energy  1.005->1.006x damage per missing energy
compound lens arc adds 25->30 degrees
instability 2->2.5x damage when damage taken is 1x
constraint: after 30->40 seconds spawn WIMPs
constraint: 0.1->0.3x damage after getting power ups
renamed holographic principle -> charmed baryons

updates to community map: downpour
updated lasers in labs and testChamber to the new more realistic laser

bugs
  returning to the old console.log system from last patch
    I rather read bugs in the browser console not the n-gon console
  bots properly follow player when level flips vertically
  community map: arena's sword is properly removed at end of level
  rewrote shaped charge to be better at protecting you from all explosions
  pause correctly lists both mobs types for the level
  for quasiparticles "boost" replaces ammo in more edge cases
  bug with removing surfactant setting b.activeGun false and crashing game with checking active gun
    not sure if this is fixed or not?
This commit is contained in:
landgreen
2024-11-12 20:16:17 -08:00
parent 8bb8222b73
commit 1fde74d65a
10 changed files with 1254 additions and 476 deletions

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -23,7 +23,7 @@ const b = {
}, },
fire() { }, fire() { },
fireNormal() { fireNormal() {
if (b.inventory.length && b.activeGun !== null) { if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire)) { if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire)) {
if (b.guns[b.activeGun].ammo > 0) { if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo() b.fireWithAmmo()
@@ -36,7 +36,7 @@ const b = {
} }
}, },
fireNotMove() { //added && player.speed < 0.5 && m.onGround fireNotMove() { //added && player.speed < 0.5 && m.onGround
if (b.inventory.length && b.activeGun !== null) { if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire) && player.speed < 2.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire) && player.speed < 2.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
if (b.guns[b.activeGun].ammo > 0) { if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo() b.fireWithAmmo()
@@ -49,7 +49,7 @@ const b = {
} }
}, },
fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire)
if (b.inventory.length && b.activeGun !== null) { if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) {
if (b.guns[b.activeGun].ammo > 0) { if (b.guns[b.activeGun].ammo > 0) {
b.fireWithAmmo() b.fireWithAmmo()
@@ -60,7 +60,7 @@ const b = {
} }
}, },
fireFloat() { //added && player.speed < 0.5 && m.onGround fireFloat() { //added && player.speed < 0.5 && m.onGround
if (b.inventory.length && b.activeGun !== null) { if (b.inventory.length && (b.activeGun !== null && b.activeGun !== undefined)) {
if (input.fire && (!input.field || m.fieldFire)) { if (input.fire && (!input.field || m.fieldFire)) {
if (m.fireCDcycle < m.cycle) { if (m.fireCDcycle < m.cycle) {
if (b.guns[b.activeGun].ammo > 0) { if (b.guns[b.activeGun].ammo > 0) {
@@ -116,7 +116,7 @@ const b = {
} }
}, },
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to
if (tech.crouchAmmoCount && m.crouch && b.activeGun !== null) { if (tech.crouchAmmoCount && m.crouch && (b.activeGun !== null && b.activeGun !== undefined)) {
tech.crouchAmmoCount-- tech.crouchAmmoCount--
if ((tech.crouchAmmoCount) % 2) { if ((tech.crouchAmmoCount) % 2) {
b.guns[b.activeGun].ammo++; b.guns[b.activeGun].ammo++;
@@ -377,7 +377,7 @@ const b = {
explosion(where, radius, color = "rgba(255,25,0,0.6)", reducedKnock = 1) { // typically explode is used for some bullets with .onEnd explosion(where, radius, color = "rgba(255,25,0,0.6)", reducedKnock = 1) { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius radius *= tech.explosiveRadius
let dist, sub, knock; let knock;
let dmg = radius * 0.019 let dmg = radius * 0.019
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) { if (tech.isSmallExplosion) {
@@ -385,10 +385,13 @@ const b = {
radius *= 0.7 radius *= 0.7
dmg *= 1.7 dmg *= 1.7
} }
let sub = Vector.sub(where, player.position);
let dist = Vector.magnitude(sub);
if (tech.isSmartRadius && radius > dist - 50) radius = Math.max(dist - 50, 1)
if (tech.isExplodeRadio) { //radiation explosion if (tech.isExplodeRadio) { //radiation explosion
radius *= 1.25; //alert range radius *= 1.25; //alert range
if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1) // if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
color = "rgba(25,139,170,0.25)" color = "rgba(25,139,170,0.25)"
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: where.x, x: where.x,
@@ -425,7 +428,7 @@ const b = {
} }
} }
} else { //normal explosions } else { //normal explosions
if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1) // if (tech.isSmartRadius) radius = Math.max(Math.min(radius, Vector.magnitude(Vector.sub(where, player.position)) - 25), 1)
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: where.x, x: where.x,
y: where.y, y: where.y,
@@ -444,9 +447,6 @@ const b = {
//player damage and knock back //player damage and knock back
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
sub = Vector.sub(where, player.position);
dist = Vector.magnitude(sub);
if (dist < radius) { if (dist < radius) {
if (simulation.dmgScale) { if (simulation.dmgScale) {
const harm = tech.isExplosionHarm ? 0.067 : 0.05 const harm = tech.isExplosionHarm ? 0.067 : 0.05
@@ -7716,10 +7716,7 @@ const b = {
} else { } else {
m.fireCDcycle = m.cycle m.fireCDcycle = m.cycle
m.energy -= drain m.energy -= drain
const where = { const where = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) }
x: m.pos.x + 20 * Math.cos(m.angle),
y: m.pos.y + 20 * Math.sin(m.angle)
}
b.laser(where, { b.laser(where, {
x: where.x + 3000 * Math.cos(m.angle), x: where.x + 3000 * Math.cos(m.angle),
y: where.y + 3000 * Math.sin(m.angle) y: where.y + 3000 * Math.sin(m.angle)

View File

@@ -13,7 +13,9 @@ Math.hash = s => {
// document.getElementById("seed").placeholder = Math.initialSeed = Math.floor(Date.now() % 100000) //random every time: just the time in milliseconds UTC // document.getElementById("seed").placeholder = Math.initialSeed = Math.floor(Date.now() % 100000) //random every time: just the time in milliseconds UTC
window.addEventListener('error', error => { window.addEventListener('error', error => {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${error.message} <u>${error.filename}:${error.lineno}</u>`) // simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${error.message} <u>${error.filename}:${error.lineno}</u>`)
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
}); });
document.getElementById("seed").placeholder = Math.initialSeed = String(Math.floor(Date.now() % 100000)) document.getElementById("seed").placeholder = Math.initialSeed = String(Math.floor(Date.now() % 100000))
@@ -512,7 +514,7 @@ ${botText}
<span style="float: right;">mouse (${simulation.mouseInGame.x.toFixed(0)}, ${simulation.mouseInGame.y.toFixed(0)})</span> <span style="float: right;">mouse (${simulation.mouseInGame.x.toFixed(0)}, ${simulation.mouseInGame.y.toFixed(0)})</span>
<br>cycles ${m.cycle} <br>cycles ${m.cycle}
<span style="float: right;">velocity (${player.velocity.x.toFixed(2)}, ${player.velocity.y.toFixed(2)})</span> <span style="float: right;">velocity (${player.velocity.x.toFixed(2)}, ${player.velocity.y.toFixed(2)})</span>
<br>mobs ${mob.length} (${spawn.pickList[0]}, ${spawn.pickList[0]}) <br>mobs ${mob.length} (${spawn.pickList[0]}, ${spawn.pickList[1]})
<span style="float: right;">blocks ${body.length}</span> <span style="float: right;">blocks ${body.length}</span>
<br>bullets ${bullet.length} <br>bullets ${bullet.length}
<span style="float: right;">power ups ${powerUp.length}</span> <span style="float: right;">power ups ${powerUp.length}</span>

File diff suppressed because it is too large Load Diff

View File

@@ -455,6 +455,7 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
spawn.setSpawnList(); //new mob types spawn.setSpawnList(); //new mob types
level.isFlipped = false
simulation.clearNow = true; //triggers a map reset simulation.clearNow = true; //triggers a map reset
m.switchWorlds() m.switchWorlds()
@@ -3389,7 +3390,7 @@ const m = {
case 4: //assembler case 4: //assembler
return `<strong>+${(0.6 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second` return `<strong>+${(0.6 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma case 5: //plasma
return `<strong>${(1 + 0.015 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>` return `<strong>${(1 + 0.025 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation case 6: //time dilation
return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking case 7: //cloaking

View File

@@ -285,7 +285,7 @@ const powerUps = {
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) { if (isCanceled) {
if (tech.isCancelDuplication) { if (tech.isCancelDuplication) {
const value = 0.05 const value = 0.06
tech.duplication += value tech.duplication += value
simulation.inGameConsole(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${value}`) simulation.inGameConsole(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${value}`)
simulation.circleFlare(value); simulation.circleFlare(value);
@@ -883,7 +883,7 @@ const powerUps = {
const couplingExtraAmmo = (m.fieldMode === 10 || m.fieldMode === 0) ? 1 + 0.04 * m.coupling : 1 const couplingExtraAmmo = (m.fieldMode === 10 || m.fieldMode === 0) ? 1 + 0.04 * m.coupling : 1
if (b.inventory.length > 0) { if (b.inventory.length > 0) {
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)') powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics if (tech.isAmmoForGun && (b.activeGun !== null && b.activeGun !== undefined)) { //give extra ammo to one gun only with tech logistics
const name = b.guns[b.activeGun] const name = b.guns[b.activeGun]
if (name.ammo !== Infinity) { if (name.ammo !== Infinity) {
if (tech.ammoCap) { if (tech.ammoCap) {
@@ -1618,7 +1618,7 @@ const powerUps = {
powerUps.spawn(x, y - 40, "heal", false) powerUps.spawn(x, y - 40, "heal", false)
} }
if (tech.isResearchReality) powerUps.spawnDelay("research", 6) if (tech.isResearchReality) powerUps.spawnDelay("research", 6)
if (tech.isBanish) powerUps.spawnDelay("research", 2) if (tech.isBanish) powerUps.spawnDelay("research", 3)
if (tech.isCouplingNoHit) powerUps.spawnDelay("coupling", 9) if (tech.isCouplingNoHit) powerUps.spawnDelay("coupling", 9)
// if (tech.isRerollDamage) powerUps.spawnDelay("research", 1) // if (tech.isRerollDamage) powerUps.spawnDelay("research", 1)
} }
@@ -1735,9 +1735,10 @@ const powerUps = {
} }
//count big power ups and small power ups //count big power ups and small power ups
let options = ["heal", "research", "ammo"] let options = ["heal", "research", tech.isBoostReplaceAmmo ? "boost" : "ammo"]
if (m.coupling) options.push("coupling") if (m.coupling) options.push("coupling")
if (tech.isBoostPowerUps) options.push("boost") if (tech.isBoostPowerUps) options.push("boost")
let bigIndexes = [] let bigIndexes = []
let smallIndexes = [] let smallIndexes = []
for (let i = 0; i < powerUp.length; i++) { for (let i = 0; i < powerUp.length; i++) {

View File

@@ -2,152 +2,152 @@
//********************************************************************* //*********************************************************************
const simulation = { const simulation = {
loop() { }, //main game loop, gets set to normal or testing loop loop() { }, //main game loop, gets set to normal or testing loop
normalLoop() {
try {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
powerUps.do();
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
if (!m.isBodiesAsleep) mobs.loop();
mobs.healthBar();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.drawMapPath();
b.fire();
b.bulletRemove();
b.bulletDraw();
if (!m.isBodiesAsleep) b.bulletDo();
simulation.drawCircle();
simulation.runEphemera();
ctx.restore();
} catch (error) {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
} finally {
simulation.drawCursor();
}
},
testingLoop() {
try {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.wireFrame();
if (input.fire && m.fireCDcycle < m.cycle) {
m.fireCDcycle = m.cycle + 15; //fire cooldown
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
console.log(mob[i])
}
}
}
simulation.draw.cons();
simulation.draw.testing();
simulation.drawCircle();
simulation.runEphemera();
simulation.constructCycle()
} catch (error) {
simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
} finally {
ctx.restore();
simulation.testingOutput();
simulation.drawCursor();
}
},
// normalLoop() { // normalLoop() {
// simulation.gravity(); // try {
// Engine.update(engine, simulation.delta); // simulation.gravity();
// simulation.wipe(); // Engine.update(engine, simulation.delta);
// simulation.textLog(); // simulation.wipe();
// if (m.onGround) { // simulation.textLog();
// m.groundControl() // if (m.onGround) {
// } else { // m.groundControl()
// m.airControl() // } else {
// m.airControl()
// }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// powerUps.do();
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) mobs.loop();
// mobs.healthBar();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.drawMapPath();
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// simulation.drawCircle();
// simulation.runEphemera();
// ctx.restore();
// } catch (error) {
// simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
// } finally {
// simulation.drawCursor();
// } // }
// m.move();
// m.look();
// simulation.camera();
// level.custom();
// powerUps.do();
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) mobs.loop();
// mobs.healthBar();
// m.draw();
// m.hold();
// level.customTopLayer();
// simulation.draw.drawMapPath();
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// simulation.drawCircle();
// simulation.runEphemera();
// ctx.restore();
// simulation.drawCursor();
// }, // },
// testingLoop() { // testingLoop() {
// simulation.gravity(); // try {
// Engine.update(engine, simulation.delta); // simulation.gravity();
// simulation.wipe(); // Engine.update(engine, simulation.delta);
// simulation.textLog(); // simulation.wipe();
// if (m.onGround) { // simulation.textLog();
// m.groundControl() // if (m.onGround) {
// } else { // m.groundControl()
// m.airControl() // } else {
// } // m.airControl()
// m.move(); // }
// m.look(); // m.move();
// simulation.camera(); // m.look();
// level.custom(); // simulation.camera();
// m.draw(); // level.custom();
// m.hold(); // m.draw();
// level.customTopLayer(); // m.hold();
// simulation.draw.wireFrame(); // level.customTopLayer();
// if (input.fire && m.fireCDcycle < m.cycle) { // simulation.draw.wireFrame();
// m.fireCDcycle = m.cycle + 15; //fire cooldown // if (input.fire && m.fireCDcycle < m.cycle) {
// for (let i = 0, len = mob.length; i < len; i++) { // m.fireCDcycle = m.cycle + 15; //fire cooldown
// if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) { // for (let i = 0, len = mob.length; i < len; i++) {
// console.log(mob[i]) // if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
// console.log(mob[i])
// }
// } // }
// } // }
// simulation.draw.cons();
// simulation.draw.testing();
// simulation.drawCircle();
// simulation.runEphemera();
// simulation.constructCycle()
// } catch (error) {
// simulation.inGameConsole(`<strong style='color:red;'>ERROR:</strong> ${(error.stack && error.stack.replace(/\n/g, "<br>")) || (error.message + ` <u>${error.filename}:${error.lineno}</u>`)}`);
// } finally {
// ctx.restore();
// simulation.testingOutput();
// simulation.drawCursor();
// } // }
// simulation.draw.cons();
// simulation.draw.testing();
// simulation.drawCircle();
// simulation.runEphemera();
// simulation.constructCycle()
// ctx.restore();
// simulation.testingOutput();
// simulation.drawCursor();
// }, // },
normalLoop() {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
powerUps.do();
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
if (!m.isBodiesAsleep) mobs.loop();
mobs.healthBar();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.drawMapPath();
b.fire();
b.bulletRemove();
b.bulletDraw();
if (!m.isBodiesAsleep) b.bulletDo();
simulation.drawCircle();
simulation.runEphemera();
ctx.restore();
simulation.drawCursor();
},
testingLoop() {
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (m.onGround) {
m.groundControl()
} else {
m.airControl()
}
m.move();
m.look();
simulation.camera();
level.custom();
m.draw();
m.hold();
level.customTopLayer();
simulation.draw.wireFrame();
if (input.fire && m.fireCDcycle < m.cycle) {
m.fireCDcycle = m.cycle + 15; //fire cooldown
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
console.log(mob[i])
}
}
}
simulation.draw.cons();
simulation.draw.testing();
simulation.drawCircle();
simulation.runEphemera();
simulation.constructCycle()
ctx.restore();
simulation.testingOutput();
simulation.drawCursor();
},
isTimeSkipping: false, isTimeSkipping: false,
timeSkip(cycles = 60) { timeSkip(cycles = 60) {
simulation.isTimeSkipping = true; simulation.isTimeSkipping = true;
@@ -712,7 +712,7 @@ const simulation = {
mouseMove = mouseMoveDefault mouseMove = mouseMoveDefault
} }
}, },
translatePlayerAndCamera(where) { translatePlayerAndCamera(where, isTranslateBots = true) {
//infinite falling. teleport to sky after falling //infinite falling. teleport to sky after falling
const before = { x: player.position.x, y: player.position.y, } const before = { x: player.position.x, y: player.position.y, }
Matter.Body.setPosition(player, { x: where.x, y: where.y }); Matter.Body.setPosition(player, { x: where.x, y: where.y });
@@ -728,14 +728,15 @@ const simulation = {
//is there a reason to update m.pos here? //is there a reason to update m.pos here?
// m.pos.x = player.position.x; // m.pos.x = player.position.x;
// m.pos.y = playerBody.position.y - m.yOff; // m.pos.y = playerBody.position.y - m.yOff;
if (isTranslateBots) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) { if (bullet[i].botType) {
if (Vector.magnitudeSquared(Vector.sub(bullet[i].position, player.position)) > 1000000) { //far away bots teleport to player if (Vector.magnitudeSquared(Vector.sub(bullet[i].position, player.position)) > 1000000) { //far away bots teleport to player
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) })); Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) }));
Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 }); Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
} else { //close bots maintain relative distance to player on teleport } else { //close bots maintain relative distance to player on teleport
Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change)); Matter.Body.setPosition(bullet[i], Vector.sub(bullet[i].position, change));
}
} }
} }
} }
@@ -996,7 +997,7 @@ const simulation = {
simulation.makeGunHUD(); simulation.makeGunHUD();
simulation.lastLogTime = 0; simulation.lastLogTime = 0;
mobs.mobDeaths = 0 mobs.mobDeaths = 0
level.isFlipped = false
level.onLevel = 0; level.onLevel = 0;
level.levelsCleared = 0; level.levelsCleared = 0;
level.updateDifficulty() level.updateDifficulty()

View File

@@ -42,6 +42,7 @@ const spawn = {
spawn.pickList.splice(0, 1); spawn.pickList.splice(0, 1);
const push = spawn.mobTypeSpawnOrder[spawn.mobTypeSpawnIndex++ % spawn.mobTypeSpawnOrder.length] const push = spawn.mobTypeSpawnOrder[spawn.mobTypeSpawnIndex++ % spawn.mobTypeSpawnOrder.length]
spawn.pickList.push(push); spawn.pickList.push(push);
// if (spawn.mobTypeSpawnIndex > spawn.mobTypeSpawnOrder.length) spawn.mobTypeSpawnIndex = 0 // if (spawn.mobTypeSpawnIndex > spawn.mobTypeSpawnOrder.length) spawn.mobTypeSpawnIndex = 0
//each level has 2 mobs: one new mob and one from the last level //each level has 2 mobs: one new mob and one from the last level
// spawn.pickList.splice(0, 1); // spawn.pickList.splice(0, 1);
@@ -116,8 +117,8 @@ const spawn = {
secondaryBossChance(x, y) { secondaryBossChance(x, y) {
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) { if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
spawn.randomLevelBoss(x, y); spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo"); powerUps.spawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo"); powerUps.spawn(x + 30, y, "ammo");
} else { } else {
return false return false
} }

View File

@@ -249,18 +249,7 @@ const tech = {
} }
}, },
haveGunCheck(name, needActive = true) { haveGunCheck(name, needActive = true) {
// if ( if (b.activeGun === null || b.activeGun === undefined) return false
// !build.isExperimentSelection &&
// b.inventory.length > 2 &&
// name !== b.guns[b.activeGun].name &&
// Math.random() > 2 - b.inventory.length * 0.5
// ) {
// return false
// }
// for (i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].name === name) return true
// }
// return false
if (build.isExperimentSelection || !needActive) { if (build.isExperimentSelection || !needActive) {
for (i = 0, len = b.inventory.length; i < len; i++) { for (i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].name === name) return true if (b.guns[b.inventory[i]].name === name) return true
@@ -269,6 +258,15 @@ const tech = {
} else { //must be holding gun, this is the standard while playing } else { //must be holding gun, this is the standard while playing
return b.inventory.length > 0 && b.guns[b.activeGun].name === name return b.inventory.length > 0 && b.guns[b.activeGun].name === name
} }
// if (build.isExperimentSelection || !needActive) {
// for (i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].name === name) return true
// }
// return false
// } else { //must be holding gun, this is the standard while playing
// return b.inventory.length > 0 && b.guns[b.activeGun].name === name
// }
}, },
hasExplosiveDamageCheck() { hasExplosiveDamageCheck() {
return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
@@ -276,9 +274,9 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() { damageFromTech() {
let dmg = tech.damage * m.fieldDamage let dmg = tech.damage * m.fieldDamage
if (level.isNoDamage && (m.cycle - 180 < level.noDamageCycle)) dmg *= 0.1 if (level.isNoDamage && (m.cycle - 180 < level.noDamageCycle)) dmg *= 0.3
if (tech.isMaxHealthDamage && m.health === m.maxHealth) dmg *= 1.5 if (tech.isMaxHealthDamage && m.health === m.maxHealth) dmg *= 1.5
if (tech.noDefenseSettingDamage && m.defense() === 1) dmg *= 2 if (tech.noDefenseSettingDamage && m.defense() === 1) dmg *= 2.5
if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 3 if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 3
if (tech.isPowerUpDamage) dmg *= 1 + 0.07 * powerUp.length if (tech.isPowerUpDamage) dmg *= 1 + 0.07 * powerUp.length
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4 if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4
@@ -288,7 +286,7 @@ const tech = {
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01) if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length
if (powerUps.boost.endCycle > simulation.cycle) dmg *= 1 + powerUps.boost.damage if (powerUps.boost.endCycle > simulation.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.025 * m.coupling
if (tech.isVerlet) dmg *= 3 if (tech.isVerlet) dmg *= 3
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.71828 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.71828
@@ -299,7 +297,7 @@ const tech = {
if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count) if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count)
if (tech.isBotDamage) dmg *= 1 + 0.04 * b.totalBots() if (tech.isBotDamage) dmg *= 1 + 0.04 * 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.5 * Math.max(0, m.maxEnergy - m.energy) if (tech.isLowEnergyDamage) dmg *= 1 + 0.6 * Math.max(0, m.maxEnergy - m.energy)
if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage; if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01 if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
@@ -2874,7 +2872,7 @@ const tech = {
{ {
name: "Gibbs free energy", name: "Gibbs free energy",
descriptionFunction() { descriptionFunction() {
return `<strong>1.005x</strong> <strong class='color-d'>damage</strong> for each missing <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em>` return `<strong>1.006x</strong> <strong class='color-d'>damage</strong> for each missing <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3086,7 +3084,7 @@ const tech = {
{ {
name: "instability", name: "instability",
descriptionFunction() { descriptionFunction() {
return `<strong>2x</strong> <strong class='color-d'>damage</strong> while your <strong class='color-defense'>damage taken</strong> is <strong>1.00x</strong><br><em style ="float: right;">(current damage taken = ${(m.defense()).toFixed(2)}x)</em>` return `<strong>2.5x</strong> <strong class='color-d'>damage</strong> while your <strong class='color-defense'>damage taken</strong> is <strong>1.00x</strong><br><em style ="float: right;">(current damage taken = ${(m.defense()).toFixed(2)}x)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3597,7 +3595,7 @@ const tech = {
}, },
{ {
name: "decoherence", name: "decoherence",
description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(2)}<br>${powerUps.orb.tech()} options you don't <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> won't <strong>reoccur</strong>`, description: `after a <strong>boss</strong> <strong>dies</strong> spawn ${powerUps.orb.research(3)}<br>${powerUps.orb.tech()} options you don't <strong class='color-choice'><span>ch</span><span>oo</span><span>se</span></strong> won't <strong>reoccur</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3606,7 +3604,6 @@ const tech = {
return !tech.isSuperDeterminism return !tech.isSuperDeterminism
}, },
requires: "not, superdeterminism", requires: "not, superdeterminism",
bonusResearch: 7,
effect() { effect() {
tech.isBanish = true tech.isBanish = true
}, },
@@ -3626,8 +3623,8 @@ const tech = {
description: `after observing a ${powerUps.orb.tech()} <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong><br>that <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong> is available for all <strong>all</strong> future ${powerUps.orb.tech()}`, description: `after observing a ${powerUps.orb.tech()} <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong><br>that <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong> is available for all <strong>all</strong> future ${powerUps.orb.tech()}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 3,
frequencyDefault: 1, frequencyDefault: 3,
allowed() { allowed() {
return tech.isBanish return tech.isBanish
}, },
@@ -4301,7 +4298,7 @@ const tech = {
}, },
{ {
name: "futures exchange", name: "futures exchange",
description: `clicking <strong class='color-cancel'>cancel</strong> for ${powerUps.orb.field()}, ${powerUps.orb.tech()}, or ${powerUps.orb.gun()}<br>gives <strong>+5%</strong> power up <strong class='color-dup'>duplication</strong> chance`, description: `clicking <strong class='color-cancel'>cancel</strong> for ${powerUps.orb.field()}, ${powerUps.orb.tech()}, or ${powerUps.orb.gun()}<br>gives <strong>+6%</strong> power up <strong class='color-dup'>duplication</strong> chance`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -7448,7 +7445,7 @@ const tech = {
}, },
{ {
name: "compound lens", name: "compound lens",
description: "<strong>1.4x</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+25°</strong> lens arc", description: "<strong>1.4x</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+30°</strong> lens arc",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -7459,7 +7456,7 @@ const tech = {
}, },
requires: "lens", requires: "lens",
effect() { effect() {
b.guns[11].arcRange += 25 * Math.PI / 180 / 2 b.guns[11].arcRange += 30 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.4 b.guns[11].lensDamageOn += 0.4
}, },
remove() { remove() {
@@ -8763,7 +8760,7 @@ const tech = {
}, },
{ {
name: "vacuum fluctuation", name: "vacuum fluctuation",
description: `use ${powerUps.orb.research(3)}<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`, description: `use ${powerUps.orb.research(2)}<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8777,14 +8774,16 @@ const tech = {
tech.fieldDuplicate = 0.11 tech.fieldDuplicate = 0.11
powerUps.setPowerUpMode(); //needed after adjusting duplication chance powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
for (let i = 0; i < 3; i++) { for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
}, },
remove() { remove() {
tech.fieldDuplicate = 0 tech.fieldDuplicate = 0
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance if (this.count) {
if (this.count > 0) powerUps.research.changeRerolls(3) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
powerUps.research.changeRerolls(2)
}
} }
}, },
{ {
@@ -8900,7 +8899,7 @@ const tech = {
} }
}, },
{ {
name: "charmed baryons", name: "holographic principle",
description: `<strong>0.8x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong class='color-worm'>wormholes</strong> cost <strong>zero</strong> <strong class='color-f'>energy</strong>`, description: `<strong>0.8x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong class='color-worm'>wormholes</strong> cost <strong>zero</strong> <strong class='color-f'>energy</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
@@ -9694,7 +9693,7 @@ const tech = {
effect() { effect() {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp) { if (mob[i].isDropPowerUp) {
powerUps.directSpawn(mob[i].position.x, mob[i].position.y, "ammo"); powerUps.spawn(mob[i].position.x, mob[i].position.y, "ammo");
mob[i].death(); mob[i].death();
} }
} }
@@ -11701,7 +11700,7 @@ const tech = {
bc.activated = false 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 === 'tech') powerUps.spawn(m.pos.x, m.pos.y, "tech");
if (ev.data === 'death') { if (ev.data === 'death') {
m.death() m.death()
bc.close(); //end session bc.close(); //end session

105
todo.txt
View File

@@ -1,16 +1,30 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: Halbach array - throwing a block will also throw other nearby blocks new level substructure
featured element - motion triggered lasers
tech non-renewables now spawns ammo, but ammo can't be picked up futures exchange 5->6% duplication per cancel
grenade tech that cause multiple explosions have less knock back for mobs plasma torch coupling 0.015->0.025x damage per coupling
constraint: 0->0.5x healing Gibbs free energy 1.005->1.006x damage per missing energy
wormhole 7->8% duplication compound lens arc adds 25->30 degrees
many worlds takes a few frames between each tech given instability 2->2.5x damage when damage taken is 1x
constraint: after 30->40 seconds spawn WIMPs
constraint: 0.1->0.3x damage after getting power ups
renamed holographic principle -> charmed baryons
bug fixes updates to community map: downpour
harpoon ammo gain on autonomous defense fixed updated lasers in labs and testChamber to the new more realistic laser
constraints are properly randomized again
bugs
returning to the old console.log system from last patch
I rather read bugs in the browser console not the n-gon console
bots properly follow player when level flips vertically
community map: arena's sword is properly removed at end of level
rewrote shaped charge to be better at protecting you from all explosions
pause correctly lists both mobs types for the level
for quasiparticles "boost" replaces ammo in more edge cases
bug with removing surfactant setting b.activeGun false and crashing game with checking active gun
not sure if this is fixed or not?
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -50,14 +64,39 @@ player can become crouched while not touching the ground if they exit the ground
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
rework focuser mobs to fire blue laser instead of charging player
like in classic 7-1-2017
this makes more sense that a bean is focusing
!!conformal - similar rules for small and big scales linked to holographic principle
!!holonomy - parallel transport of a vector leads to movement (applies to curved space)
when far away from your wormhole regenerate 1% of your max energy per second
when far away from your wormhole reduce damage taken
heal last hit damage after enter wormhole
!!quasar - plasma torch from both ends
only after wormhole eats a block fire?
or just increase plasma length after eating block?
new level element - motion trigger for laser
new level heist
above - a building with rooms and doors like office/warehouse
below - long indoor tunnels like sewers
dark colors
narrow branching paths
elements
motion triggered lasers
doors opened by buttons
button that opens 1 door, but closes another when down
make the button down state easier, have extra power ups
make a text orb for JUNK text to make JUNK more clear make a text orb for JUNK text to make JUNK more clear
extended vertical flip to edge cases: extended vertical flip to edge cases:
!!stored circular graphics simulation.drawList.push !!stored circular graphics simulation.drawList.push
new level based laser element
!!update new version into other levels
procedural animation procedural animation
https://www.youtube.com/watch?v=qlfh_rv6khY https://www.youtube.com/watch?v=qlfh_rv6khY
@@ -839,9 +878,6 @@ mob/boss that fires a laser at player, but give player time to avoid
they target where player was 1 second ago they target where player was 1 second ago
they turn to face player? they turn to face player?
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
require electric reactive armor?
Plasma Burner: upgrade for plasma torch, basically just a jet engine. does high damage, but short range, mostly for player movement. Plasma Burner: upgrade for plasma torch, basically just a jet engine. does high damage, but short range, mostly for player movement.
maybe reduce gravity to really low then apply a vector away from mouse direction maybe reduce gravity to really low then apply a vector away from mouse direction
@@ -851,17 +887,6 @@ auto-gon - auto battler with n-gon mob AI and tech
similar research and tech system to n-gon similar research and tech system to n-gon
some mobs can fire player weapons some mobs can fire player weapons
tech: relativistic jets:
small particles that shot out from front and back poles and end up in a wide variety of spirals
slow trickle when charging and several more when firing
Tech: Make player smol
adapt the cloaking graphics to make a flashlight cone visual effect
put code in level.do?
be nice if block throwing had a projected path
Pilot wave tech Pilot wave tech
Energy use is increased, but you can now shape blocks using pressure Energy use is increased, but you can now shape blocks using pressure
Grouping blocks will merge them into a massive ball Grouping blocks will merge them into a massive ball
@@ -1234,11 +1259,8 @@ look up sci-fi science ideas here https://projectrho.com/public_html/rocket/
possible names for tech possible names for tech
sidereal - with respect to the stars (an extra rotation for time keeping) sidereal - with respect to the stars (an extra rotation for time keeping)
holonomy - parallel transport of a vector leads to movement (applies to curved space)
holographic - 2-D surface can predict the 3-D space behind it? I think
entropic gravity - gravity is emergent in a holographic way entropic gravity - gravity is emergent in a holographic way
(maybe a field tech for negative mass) (maybe a field tech for negative mass)
conformal - similar rules for small and big scales linked to holographic principle
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other. hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
swarm intelligence - for a drone tech swarm intelligence - for a drone tech
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
@@ -1307,8 +1329,11 @@ possible names for tech
cork - used as a heat shield for rockets cork - used as a heat shield for rockets
P = NP - something with speeding up calculation times P = NP - something with speeding up calculation times
transistivity - something where a>b and b>c -> a>c transistivity - something where a>b and b>c -> a>c
lenticular - looks different from different angles (lasers?) lenticular - looks different from different angles (lasers?, cloaking?)
every few seconds pick a random skin tech?
De Sitter space - simple model of universe related to general relativity (mass-energy?) De Sitter space - simple model of universe related to general relativity (mass-energy?)
active optics - something with lasers? maybe something with diffuse beam getting smaller
Quintessence - related to dark energy
******************************************************* DESIGN ****************************************************** ******************************************************* DESIGN ******************************************************
@@ -1333,3 +1358,23 @@ list of powerful synergies
electronegativity and high energy? electronegativity and high energy?
electronegativity + anyon + duplication + Maxwells demon + interest + pair production electronegativity + anyon + duplication + Maxwells demon + interest + pair production
chain reaction + invulnerable + Abelian group + parasitism = clear all mobs on level chain reaction + invulnerable + Abelian group + parasitism = clear all mobs on level
************************************************* COMMUNITY LINKS *************************************************
load old commits
www.cornbread2100.com/n-gon-loader
n-gon fork
kgurchiek.github.io/n-gon-portal-gun
3xiondev.github.io/n-gon-upgraded
coaldeficit.github.io/c-gon
c-rxxp-y.github.io/n-gon-enhanced
bookmarlet
github.com/Whyisthisnotavalable/n-scythe
github.com/kgurchiek/n-gon-mobile
github.com/kgurchiek/n-gon-controller
text
ngon.fandom.com/wiki/N-gon
github.com/3xionDev/n-docs