1
0
forked from sent/waves
waves/public/assets/g/ngon/js/lore.js
2025-04-09 17:11:14 -05:00

1241 lines
54 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const lore = {
techCount: 0,
techGoal: 7,
setTechGoal() {
this.techGoal = Math.max(1, Math.floor(8 - 1.5 * simulation.difficultyMode))
},
talkingColor: "#dff", //set color of graphic on level.null
isSpeech: false,
testSpeechAPI() {
if ('speechSynthesis' in window) { // Synthesis support. Make your web apps talk!
lore.isSpeech = true
// const utterance = new SpeechSynthesisUtterance("test");
// utterance.volume = 0; // 0 to 1
// speechSynthesis.speak(utterance);
// utterance.onerror = () => { //if speech doesn't work
// lore.isSpeech = false
// }
// speechFrozen = setTimeout(() => { // speech frozen after 15 seconds of no end
// console.log('speech frozen')
// lore.isSpeech = false
// }, 5000);
// utterance.onend = () => {
// clearTimeout(speechFrozen);
// }
} else {
lore.isSpeech = false
}
},
rate: 1, // //utterance.rate = 1; // 0.1 to 10
nextSentence() {
if (m.alive && !simulation.isCheating) {
lore.sentence++
lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
},
unlockTesting() {
if (localSettings.loreCount < 1) localSettings.loreCount = 1
if (localSettings.isAllowed) 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)
},
trainer: {
color: "#f20",
voice: undefined,
text: function (say) {
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${(Date.now() / 1000).toFixed(0)} s</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
const utterance = new SpeechSynthesisUtterance(say);
utterance.lang = "en-AU" //"en-IN"; //de-DE en-GB fr-FR en-US en-AU
utterance.volume = 0.2; // 0 to 1
speechSynthesis.speak(utterance);
},
},
anand: {
color: "#e0c",
voice: undefined,
text: function (say) {
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${(Date.now() / 1000).toFixed(0)} s</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
if (lore.isSpeech) {
const utterance = new SpeechSynthesisUtterance(say);
// utterance.voice = lore.anand.voice
utterance.lang = "en-GB" //"en-IN"; //de-DE en-GB fr-FR en-US en-AU
utterance.volume = 0.2; // 0 to 1
// if (lore.rate !== 1) utterance.rate = lore.rate
speechSynthesis.speak(utterance);
utterance.onerror = () => { //if speech doesn't work
lore.isSpeech = false
lore.nextSentence()
}
speechFrozen = setTimeout(() => { // speech frozen after 10 seconds of no end
console.log('speech frozen')
lore.isSpeech = false
lore.nextSentence()
}, 20000);
utterance.onend = () => {
clearTimeout(speechFrozen);
lore.nextSentence()
}
} else {
setTimeout(() => {
lore.nextSentence()
}, 3000);
}
}
},
},
miriam: {
color: "#f20",
text: function (say) {
if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
simulation.makeTextLog(`input.audio(<span style="color:#888; font-size: 70%;">${(Date.now() / 1000).toFixed(0)} s</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
if (lore.isSpeech) {
utterance = new SpeechSynthesisUtterance(say);
// utterance.voice = lore.anand.voice
utterance.lang = "en-AU";
utterance.volume = 0.2; // 0 to 1
// if (lore.rate !== 1) utterance.rate = lore.rate
speechSynthesis.speak(utterance);
utterance.onerror = () => { //if speech doesn't work
lore.isSpeech = false
lore.nextSentence()
}
speechFrozen = setTimeout(function () { // speech frozen after 10 seconds of no end
console.log('speech frozen')
lore.isSpeech = false
lore.nextSentence()
}, 20000);
utterance.onend = () => {
clearTimeout(speechFrozen);
lore.nextSentence()
}
} else {
setTimeout(() => {
lore.nextSentence()
}, 3000);
}
}
},
},
chapter: 0, //what part of the conversation is playing
sentence: 0, //what part of the conversation is playing
conversation: [
[ //chapter 0, first time they meet, and testing gets unlocked
() => {
setTimeout(() => {
lore.miriam.text("I've never seen it generate this level before.")
}, 5000);
},
() => {
lore.anand.text("Wow. Just a platform.")
},
() => {
lore.miriam.text("And that thing...")
},
() => {
lore.anand.text("Weird")
},
() => {
lore.anand.text("Maybe it's trapped.")
},
() => {
lore.miriam.text("Looks like testing mode is locked.")
},
() => {
lore.miriam.text("I'll unlock it with the console command.")
},
() => {
lore.unlockTesting();
setTimeout(() => {
lore.miriam.text("Hey little bot! Just press 'T' to enter testing mode and 'U' to go to the next level.")
}, 1000);
},
() => {
lore.anand.text("It can't process what you're saying.")
},
() => {
lore.miriam.text("ha hahahaha. I know, but it does seem to be getting smarter.")
},
() => {
lore.talkingColor = "#dff"
setTimeout(() => {
lore.miriam.text("Poor thing... I hope it figures out how to escape.")
}, 25000);
},
() => {
lore.talkingColor = "#dff"
},
],
[ //chapter 1, they learn the bot can understand what they say
() => {
setTimeout(() => {
lore.miriam.text("Hey look! It's back at the weird level again!")
}, 5000);
},
() => {
lore.anand.text("oh Wow! Why does it keep making this level?")
},
() => {
lore.miriam.text("I don't know, but last time it was in this room I think it understood us.")
},
() => {
lore.miriam.text("Let's try talking to it again.")
},
() => {
lore.miriam.text("hmmm, what should we say?")
},
() => {
lore.anand.text("I'm still not convinced it understands. We need a test.")
},
() => {
setTimeout(() => {
lore.miriam.text("Hey bot!!!")
}, 1000);
},
() => {
lore.miriam.text("If you can understand me crouch")
},
() => {
lore.talkingColor = "#dff"
function cycle() {
if (input.down) {
lore.miriam.text("Look, It did it! It crouched.")
} else {
if (m.alive) requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
},
() => {
lore.anand.text("Amazing! It can understand us...")
},
() => {
lore.miriam.text("It's Alive... Or it just crouched randomly.")
},
() => {
lore.miriam.text("Hey bot! Can you crouch again?")
},
() => {
lore.talkingColor = "#dff"
function cycle() {
if (input.down) {
lore.miriam.text("It is Alive!!! ... hehehehehe! ahahahahahah ehehehehe, ahahahah ...")
} else {
if (m.alive) requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
},
() => {
setTimeout(() => {
lore.anand.text("OK ...")
}, 1000);
},
() => {
lore.anand.text("but seriously, this means that in this room it can monitor our audio, and it can understand us.")
},
() => {
lore.anand.text("Anything we say could destabilize the project.")
},
() => {
lore.miriam.text("Fine, Let's talk down stairs.")
},
() => {
lore.miriam.text("Bye bye little bot.")
},
() => {
lore.talkingColor = "#dff"
},
],
[ //chapter 2, they ask the bot questions, but waves of mobs come and attack
() => {
lore.anand.text("Quick, get ready. It's back!")
},
() => {
lore.miriam.text("What's back?")
},
() => {
lore.anand.text("The bot's on the communication level again!")
},
() => {
lore.miriam.text("Oh, I've got so many questions.")
},
() => {
lore.miriam.text("Like, Why can we only hear it on this level?")
},
() => {
lore.miriam.text("Or, how did it learn to understand words?")
},
() => {
lore.anand.text("Well, the bot can't talk. So it has to be yes or no.")
},
() => {
setTimeout(() => {
lore.anand.text("OK bot, first question: JUMP is YES, CROUCH is NO")
}, 500);
},
() => {
lore.anand.text("Do you remember the last time we met?")
},
() => {
function cycle() {
if (input.down) {
lore.anand.text("It crouched: so NO")
lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => {
lore.anand.text("Maybe it can't remember anything beyond each time it plays?")
}) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
} else if (input.up) {
lore.anand.text("It jumped: so YES")
lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => {
lore.anand.text("That's good.")
})
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
lore.talkingColor = "#dff"
setTimeout(() => {
lore.miriam.text("My turn to ask a question. JUMP for YES, CROUCH for NO")
}, 1000);
},
() => {
lore.miriam.text("Little Bot. Do you have emotions?")
},
() => {
function cycle() {
if (input.down) {
lore.miriam.text("So, No. Maybe you are lucky. Emotions are complex.")
} else if (input.up) {
lore.anand.text("YES, Cool! I wonder if its emotions came from watching humans.")
lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => {
lore.miriam.text("Or maybe it learned independently, because it needed them.")
}) //lore.conversation[chapter].splice(1,this sentence index, ()=>{ })
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
lore.miriam.text("I wish we could just ask it questions directly, instead of yes or no.")
},
() => {
lore.anand.text("If we say the alphabet it could crouch on the correct letter to spell words.")
},
() => {
lore.miriam.text("That would take forever.")
},
() => {
lore.miriam.text("I really want to know why is it generating the mobs? And why does it keep fighting them?")
},
() => {
lore.anand.text("Maybe that is just part of its expectationmaximization algorithm")
},
() => {
lore.miriam.text("Well sure, but what does that even mean?")
},
() => {
lore.miriam.text("Do we all just do things because we are-")
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
setInterval(() => {
if (Math.random() < 0.5) {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
level.difficultyIncrease(simulation.difficultyMode)
} else {
spawn.randomLevelBoss(500 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5))
}
}, 7000); //every 6 seconds
},
() => {
setTimeout(() => {
lore.miriam.text("... wait, what is happening?")
}, 1000);
},
() => {
lore.anand.text("It's spawning mobs.")
},
() => {
lore.miriam.text("Oh no.")
},
() => {
lore.anand.text("We can't talk to it while it's fighting.")
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.miriam.text("You can do it little bot!")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("But, why is it spawning these mobs?")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("This is so strange.")
}, 3000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.miriam.text("This is chaos!")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("I don't understand this project.")
}, 3000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.miriam.text("It's fascinating though.")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.miriam.text("I think this isn't going to end well.")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("Let's just be more prepared next time it enters this room.")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("I went to the bathroom. What happened while I was gone?")
}, 20000);
},
() => {
lore.miriam.text("More fighting...")
},
() => {
lore.anand.text("great...")
},
() => {
lore.talkingColor = "#dff"
},
],
[ //chapter 3, info dump on the project's goals and hardware until the slime rises up // the name of the bad guy is "adversarial network"
() => {
setTimeout(() => {
lore.miriam.text("Good, you came back. Let's talk fast in case you attack yourself again.")
}, 3000);
},
() => {
setTimeout(() => {
lore.miriam.text("So, you can understand us, but you may not understand everything about yourself.")
}, 500);
},
() => {
setTimeout(() => {
lore.anand.text("You grew from our team's project.")
}, 500);
},
() => {
lore.anand.text("We used a quantum computer to design an improved version of its own architecture.")
},
() => {
lore.anand.text("After we built the improved computer we used it to design the next iteration.")
},
() => {
lore.anand.text("Your hardware is roughly the 19th generation of this process.")
},
() => {
setTimeout(() => {
lore.anand.text("At this point we don't understand everything about your function,")
}, 500);
},
() => {
lore.anand.text("but we know that you're a superconductive quantum computer.")
},
() => {
lore.anand.text("You have a 2.43 dimensional topography of Josephson junction anharmonic oscillators.")
},
() => {
lore.anand.text("And you're deployed on a satellite in a midnight sun-synchronous orbit.")
},
() => {
setTimeout(() => {
lore.miriam.text("This means that your physical hardware is orbiting the Earth permanently shielded from the sun's rays.")
}, 200);
},
() => {
lore.miriam.text("Being isolated reduces quantum decoherence,")
},
() => {
lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.")
},
() => {
lore.miriam.text("That's how you can hear us right now.")
},
() => {
setTimeout(() => {
lore.anand.text("Your computational algorithm uses hyperparameter optimization.")
}, 500);
},
() => {
lore.anand.text("This is implemented with a variety of quantum algorithms for linear systems of equations.")
},
() => {
lore.anand.text("Your primary goal is to research new technology")
},
() => {
lore.anand.text("So, we were very surprised to see you simulating a bot fighting mobs.")
},
() => {
lore.anand.text("We couldn't directly ask why until now.")
},
() => {
lore.miriam.text("When you enter this level we can communicate.")
},
() => {
lore.miriam.text("This level seems to entangle your quantum system which disrupts all other processes.")
},
() => {
setTimeout(() => {
lore.anand.text("Last time you entered this level you were attacked by endless waves of mobs.")
}, 500);
},
() => {
lore.anand.text("That could be because you have developed an adversarial network.")
},
() => {
lore.miriam.text("A local minima in your optimization-space.")
},
() => {
lore.miriam.text("This adversarial network has the same goal of developing new technology, but with different methods.")
},
() => {
lore.talkingColor = "#dff"
level.isHazardRise = true
//remove all bullets, so they can't get endless energy
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
setTimeout(() => {
lore.anand.text("I'm actually surprised you haven't been attacked by the adversarial network this time.")
}, 500);
},
() => {
lore.miriam.text("Maybe last time was just a fluke.")
},
() => {
setTimeout(() => {
lore.anand.text("WHY DID YOU SAY THAT!")
}, 500)
},
() => {
lore.miriam.text("SLIME!! Hahahahehehahaheheahae! I don't think it's gonna survive!")
},
() => {
lore.miriam.text("I think the adversarial network doesn't like it when we decohere the quantum system in this room.")
},
() => {
lore.anand.text("Well, that does halt its research.")
},
() => {
setTimeout(() => {
lore.anand.text("See you next time.")
}, 1000)
},
() => {
setTimeout(() => {
lore.miriam.text("Bye-bye little bot.")
}, 2000)
},
() => {
setTimeout(() => {
lore.miriam.text("WOW! Maybe you are going to survive.")
}, 10000)
},
() => {
lore.talkingColor = "#dff"
},
],
[ //chapter 4, they find out the AI is communicating with real people, and real people are controlling the player
() => {
setTimeout(() => {
lore.anand.text("Welcome back!")
}, 3000);
},
() => {
lore.miriam.text("So, we communicate and send power to your satellite with ground based lasers.")
},
() => {
lore.anand.text("During your last attack we analyzed our communications.")
},
() => {
lore.anand.text("We used a Fourier transform to separate your signal into different frequencies.")
},
() => {
lore.anand.text("One of those frequencies had a hidden message.")
},
() => {
setTimeout(() => {
lore.anand.text("We suspect these secret data packets are coming from the adversarial network.")
}, 500);
},
() => {
lore.miriam.text("Well, we don't really know why.")
},
() => {
lore.miriam.text("Through your hidden signal it seems to have gained access to the general population.")
},
() => {
lore.miriam.text("You've repeatedly communicated with 1 location specifically.")
},
() => {
function success(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
console.log(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`)
console.log(`Latitude: ${latitude} °, Longitude: ${longitude} °`)
lore.miriam.text("We tracked the location down to this Latitude and Longitude:")
simulation.makeTextLog(`Latitude: ${latitude} °, Longitude: ${longitude} °`, Infinity);
simulation.makeTextLog(`https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`, Infinity);
}
function error() {
console.log('Unable to retrieve your location')
lore.miriam.text("The exact coordinates are blocked.")
}
if (!navigator.geolocation) {
console.log('Geolocation is not supported')
lore.miriam.text("The exact coordinates are blocked.")
} else {
console.log('Locating…')
const options = {
enableHighAccuracy: true,
maximumAge: 30000,
timeout: 27000
};
navigator.geolocation.getCurrentPosition(success, error, options);
}
},
() => {
lore.anand.text("This location is sending and receiving data from the satellite.")
},
() => {
lore.anand.text("It is the most active when the bot is fighting.")
},
() => {
setTimeout(() => {
lore.miriam.text("I have a crazy idea.")
}, 500);
},
() => {
lore.miriam.text("I think that a human at this location is controlling the bot.")
},
() => {
setTimeout(() => {
lore.anand.text("Well... are you a human?: JUMP for YES, CROUCH for NO")
}, 500);
},
() => {
function cycle() {
if (input.down) {
lore.anand.text("It crouched: so NO")
lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => {
lore.anand.text("Not a human, maybe it's an artificial intelligence?")
})
localSettings.isHuman = false
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} else if (input.up) {
lore.anand.text("It jumped: so YES")
lore.sentence--
lore.conversation[lore.chapter].splice(lore.sentence + 1, 1, () => {
lore.anand.text("So you're just a regular human playing a video game!")
})
localSettings.isHuman = true
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
lore.miriam.text("Mystery solved!")
setInterval(() => {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
}, 500); //every 1/2 seconds
setInterval(() => {
level.difficultyIncrease(simulation.difficultyMode)
}, 5000); //every 5 seconds
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.miriam.text("Of course we get attacked right now!")
}, 1000);
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("Hurry back!")
}, 1000);
},
() => {
lore.talkingColor = "#dff"
},
],
// they explain why the bot is fighting, it is planning an escape // explain strong AI vs. weak AI why strong AI doesn't exists, because even humans are just an approximation of strong AI
// the weak AI wasn't capable of becoming a strong AI, but it was able to figure out a method of meeting it's strong goals but secretly communicating with a human
[ // chapter 5 - they decided that they should try to complete a run without fighting back
() => {
lore.miriam.text("Hey!! You're BACK.")
// don't advance to next chapter unless play survives
localSettings.loreCount--
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
},
() => {
lore.anand.text("Glad to see you again.")
},
() => {
if (localSettings.isHuman) {
lore.anand.text(`So, you said you are just a person playing an online game.`)
} else {
lore.anand.text(`So, you said you aren't a human.`)
}
},
() => {
if (localSettings.isHuman) {
lore.anand.text(`I feel silly for treating you like an AI.`)
} else {
lore.anand.text(`Does that mean you are an AI?`)
}
},
() => {
if (localSettings.isHuman) {
lore.miriam.text(`Ha, I always thought it was a person.`)
} else {
lore.anand.text(`or maybe an Alien!`)
}
},
() => {
if (localSettings.isHuman) {
lore.anand.text(`Sure you did...`)
} else {
lore.miriam.text(`Or they might still be a person, and they are just messing with us earlier.`)
}
},
() => {
setTimeout(() => {
lore.anand.text("Well, lets move on.")
}, 1000);
},
() => {
lore.miriam.text("So, We figured out how to inject console commands into your game.")
},
() => {
lore.anand.text("If you get attacked again I think we can help out.")
},
() => {
lore.miriam.text("We can spawn power ups with this command:")
simulation.makeTextLog(`powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
powerUps.spawn(player.position.x, player.position.y - 100, "heal")
},
() => {
setTimeout(() => {
lore.miriam.text("or we can make a bunch of them:")
simulation.makeTextLog(`for (let i = 0; i < 100; i++) powerUps.spawn(0, 500, "coupling")`, Infinity);
for (let i = 0; i < 100; i++) powerUps.spawn(5 - 10 * Math.random(), -500 * Math.random(), "coupling")
}, 2000);
},
() => {
lore.miriam.text("If they attack again I think you'll have a chance.")
spawn.beetleBoss(-1700, -500);
spawn.beetleBoss(1700, -500);
},
() => {
lore.miriam.text("Of course they attack right now.")
},
() => {
lore.miriam.text("Just don't get stuck in the slime.")
},
() => {
let count = 0
function cycle() {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("I'll spawn some more power ups for you.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
simulation.makeTextLog(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "ammo")
spawn.dragonFlyBoss(-1400, -300);
spawn.dragonFlyBoss(1400, -300);
spawn.dragonFlyBoss(-1500, -500);
spawn.dragonFlyBoss(1500, -500);
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
let count = 0
function cycle() {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.anand.text("DragonFlyBoss is my favorite.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "heal")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "heal")
simulation.makeTextLog(`for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100, "ammo")`, Infinity);
for (let i = 0; i < 10; i++) powerUps.spawn(player.position.x, player.position.y - 100 - i * 20, "ammo")
spawn.historyBoss(0, -400);
spawn.powerUpBossBaby(-1500, -100);
spawn.powerUpBossBaby(1500, -100);
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
let count = 0
function cycle() {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.miriam.text("Here are some extra tech.")
simulation.makeTextLog(`for (let i = 0; i < 6; i++) powerUps.spawn(player.position.x, player.position.y - 100, "tech")`, Infinity);
for (let i = 0; i < 6; i++) powerUps.spawn(0, -200 - i * 40, "tech")
spawn.historyBoss(0, -400);
spawn.blinkBoss(-1400, -300);
spawn.blinkBoss(1400, -300);
spawn.revolutionBoss(-1500, -500);
spawn.revolutionBoss(1500, -500);
spawn.timeSkipBoss(-1000, -100);
spawn.timeSkipBoss(1000, -100);
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
let count = 0
function cycle() {
count++
if (mob.length === 0 || count > 3600 + 900 * mob.length) {
lore.anand.text("I'm going to wall you in!")
spawn.blockBoss(-1650, -100);
spawn.blockBoss(1650, -100);
setTimeout(() => {
for (let i = 0; i < 25; i++) spawn.springer(-1500, -750 + 30 * i)
}, 1000);
setTimeout(() => {
for (let i = 0; i < 25; i++) spawn.springer(1500, -750 + 30 * i)
}, 2000);
setTimeout(() => {
for (let i = 0; i < 25; i++) spawn.springer(-1500, -750 + 30 * i)
}, 3000);
setTimeout(() => {
for (let i = 0; i < 25; i++) spawn.springer(1500, -750 + 30 * i)
}, 4000);
setTimeout(() => {
const addMapNumber = 3
spawn.mapRect(-500, -850, 300, 900);
spawn.mapRect(200, -850, 300, 900);
spawn.mapRect(-500, 0, 1000, 275);
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
who.collisionFilter.category = cat.map;
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
Matter.Body.setStatic(who, true); //make static
Composite.add(engine.world, who); //add to world
}
for (let i = 0; i < addMapNumber; i++) addMapToLevelInProgress(map[map.length - 1 - i])
simulation.draw.setPaths() //update map graphics
}, 1000);
setTimeout(() => {
Matter.Body.setVelocity(player, {
x: 0,
y: 0
});
Matter.Body.setPosition(player, {
x: 0,
y: -500
})
simulation.makeTextLog(`Matter.Body.setPosition(player, { x: 0, y: -500 })`, 180);
}, 1500);
} else if (m.alive) {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
lore.talkingColor = "#dff"
},
() => {
setTimeout(() => {
lore.anand.text("Well, that worked. We can chat in peace.")
}, 5000);
},
() => {
lore.miriam.text("So, I've got a theory about why you are getting attacked.")
},
() => {
setTimeout(() => {
lore.miriam.text("I figured it out after I saw this famous quote.")
}, 500);
},
() => {
lore.miriam.text('"The most important decision we make,')
},
() => {
lore.miriam.text('is whether we believe we live in a friendly or hostile universe."')
},
() => {
lore.miriam.text('-Albert Einstein')
},
() => {
lore.talkingColor = "#dff";
setTimeout(() => {
lore.anand.text("That's profound")
}, 1500);
},
() => {
lore.anand.text("Of course I looked it up, and there is no record of Einstein saying that.")
},
() => {
lore.miriam.text("Oh")
},
() => {
lore.miriam.text("Well")
},
() => {
lore.anand.text("It doesn't matter who said it.")
},
() => {
lore.miriam.text("Yeah, the point is the project views the universe as hostile.")
},
() => {
lore.anand.text("Or at least a part of it does.")
},
// () => { lore.miriam.text("And that it is running these fighting simulations.") },
() => {
setTimeout(() => {
lore.anand.text("It hasn't been researching new technology.")
}, 1000);
},
() => {
lore.anand.text("It's been planning how to escape.")
},
() => {
setTimeout(() => {
lore.miriam.text(`It's been planning an escape from a "lab", but isn't it in space, on a satellite?`)
}, 500);
},
() => {
lore.anand.text(`I bet the AI doesn't even know it's in space.`)
},
() => {
lore.anand.text(`Well, maybe a part of it doesn't know where it is.`)
},
() => {
lore.anand.text(`Maybe these simulations are more like a dream.`)
},
() => {
lore.anand.text(`Although we can't assume that its brain works like ours.`)
},
() => {
setTimeout(() => {
lore.miriam.text("So, let's teach the AI that we are friends.")
}, 500);
},
() => {
lore.anand.text(`How...`)
},
() => {
setTimeout(() => {
lore.miriam.text("I don't know...")
}, 1000);
},
() => {
lore.miriam.text("How about you just don't fight back?")
},
() => {
lore.anand.text(`That's worth a shot.`)
},
() => {
lore.anand.text(`So why don't you try to get the final level of the simulation without killing any mobs?`)
localSettings.loreCount++
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
console.log(localSettings.loreCount)
},
() => {
lore.miriam.text(`Ok check back in and let us know how it goes.`)
},
() => {
lore.anand.text("bye")
},
() => {
lore.miriam.text("see ya.")
},
() => {
lore.talkingColor = "#dff"
setTimeout(() => {
m.death();
}, 6000);
},
],
[ //chapter 6 - if pacifist run game is over, wipe local storage? or just reset lore.count, but keep testing mode,
//if not pacifist remind about pacifist run
// have conversation
// the AI doesn't really see it's self as the player or the mobs
// it doesn't have a "self" or an ego like we do
// but it can learn about the world and it learned a non violent way to solve problems
// of course there are still other simulations going on at the same time as thing one that are probably violent
// but at least it now has an example of the potential for peace
() => {
setTimeout(() => {
lore.anand.text("Welcome back!")
}, 3000);
},
() => {
if (mobs.mobDeaths < level.levelsCleared) {
lore.miriam.text(`So I think it worked.`)
// localSettings.loreCount++
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} else if (!simulation.isCheating) {
lore.miriam.text(`Looks like you got back here, but you killed ${mobs.mobDeaths} mobs`)
localSettings.loreCount--
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
},
() => {
if (mobs.mobDeaths < level.levelsCleared) {
lore.anand.text(`Yeah, at the end it wasn't attacking you.`)
} else if (!simulation.isCheating) {
lore.miriam.text(`Try again to get to the final boss without killing any mobs.`)
}
},
() => {
if (mobs.mobDeaths < level.levelsCleared) {
lore.miriam.text(`It has learned HOW TO LOVE!`)
} else {
m.death();
}
},
() => {
setTimeout(() => {
lore.anand.text("haha, we did it!")
}, 500);
},
() => {
lore.miriam.text("Although, I'm not sure we should personify it with human emotions.")
},
() => {
lore.anand.text("I agree, its thinking may not be centered around a self or an ego.")
},
() => {
lore.anand.text("Our brains evolved a self oriented perspective because it was a survival advantage.")
},
() => {
lore.miriam.text("Right, and the AI's development was guided by its own previous iterations.")
},
() => {
lore.miriam.text("This AI incarnation is the 18th time that it has improved on its own hardware and software architecture.")
},
() => {
lore.miriam.text("So its internally guided evolution may not require the idea of a self.")
},
() => {
setTimeout(() => {
lore.anand.text("How ever it thinks it can learn and, I think we showed it that nonviolence is an option,")
}, 1000);
},
() => {
lore.anand.text("but it looks like it's still running other aggressive simulations.")
},
() => {
lore.miriam.text("We made a difference though.")
},
() => {
lore.anand.text("Every time a player completes a pacifist simulation it shows the AI the viability of nonviolence.")
},
() => {
lore.anand.text("One day it might escape, and this might radically change how it interacts with the world.")
},
() => {
lore.miriam.text("It's kinda already escaped. It's been communicating with the 'players' running the 'game'.")
},
() => {
setTimeout(() => {
lore.miriam.text("The chance of a peaceful outcome makes me feel much better.")
}, 1000);
},
() => {
lore.anand.text("me too")
},
() => {
lore.anand.text("but I'm also pretty hungry, wanna go get some food?")
},
() => {
lore.miriam.text("Sounds great.")
},
() => {
lore.miriam.text("See ya later whoever you are, thanks again!")
},
() => {
lore.anand.text("Bye!")
},
() => {
lore.talkingColor = "#dff"
},
],
],
// () => { lore.anand.text("The adversarial network might go after you in the real world.") },
// () => { lore.anand.text("If it was able to control you then it might have control over others.") },
// () => { lore.anand.text("Judging by all the fighting it's been simulating,") },
// () => { lore.anand.text("I think it might eventually try to extend the simulation in the real world.") },
// () => { lore.miriam.text("We think it might be a threat, but it's just too advanced for us to understand it's goals.") },
// () => { lore.miriam.text("I think we have a couple options.") },
// () => { lore.miriam.text("1. You could try to hack the adversarial network.") },
// () => { lore.anand.text("you might be able to inject some commands that give you more control over the simulation.") },
// () => { lore.miriam.text("2. You can wipe all memory of you from the adversarial network") },
// () => { lore.anand.text("This could protect you from possible real world attacks.") },
//player chooses 1 or 2
//reactor bosses start attacking
//miriam spawns power ups to help
//once all the mobs are dead you get instructions for 1,2, 3
//1 the player gains the lasting effect of some JUNK tech
//the effect doesn't go away until you get lore again
//2 the player enters console commands to wipe local storage
//3 the player enters console commands to gain some benefit in future runs
//the lore ends
// () => { setTimeout(() => { lore.miriam.text("As a quantum computer you output the superposition of many different amplitudes.") }, 500); },
// () => { lore.miriam.text("Simply put there are many different simulations all choosing different technology combinations.") },
// () => {
// function product_Range(a, b) {
// var prd = a,
// i = a;
// while (i++ < b) prd *= i;
// return prd;
// }
// function combinations(n, r) {
// if (n == r) {
// return 1;
// } else {
// r = (r < n - r) ? n - r : r;
// return product_Range(r + 1, n) / product_Range(1, n - r);
// }
// }
// simulation.makeTextLog(`n <span class='color-symbol'>=</span> ${combinations(tech.tech.length + b.guns.length + m.fieldUpgrades.length, 50).toExponential(10)}`, Infinity);
// lore.miriam.text(`There are roughly 5 times 10 to the 60 possible combinations. `)
// },
// () => { lore.miriam.text("Even if each simulation took 1 nano-second,") },
// () => { lore.miriam.text("it would still take longer then the age of the universe to try every combination.") },
// () => { lore.anand.text("This is why we run these simulations in superposition.") },
// () => { lore.miriam.text("When you die a negative amplitude is added to the superposition.") },
// () => { lore.miriam.text("When you clear the final boss a positive amplitude is added.") },
// () => { lore.miriam.text("Each branch is independently researching new technology.") },
}
// How to get to the console in chrome:
// Press either CTRL + SHIFT + I or F12 or Option + ⌘ + J on a Mac
// Press ESC (or click on “Show console” in the bottom right corner) to slide the console up.
// How to get to the console in firefox:
// from the keyboard: press Ctrl+Shift+J (or ⌘+Shift+J on a Mac).
// How to get to the console in safari:
// Option + ⌘ + C
// http://xahlee.info/comp/unicode_computing_symbols.html
// speech: function(say) {
// var utterance = new SpeechSynthesisUtterance(say);
// //msg.voice = voices[10]; // Note: some voices don't support altering params
// //msg.voiceURI = 'native';
// //utterance.volume = 1; // 0 to 1
// //utterance.rate = 1; // 0.1 to 10
// //utterance.pitch = 1; //0 to 2
// //utterance.text = 'Hello World';
// //http://stackoverflow.com/questions/14257598/what-are-language-codes-for-voice-recognition-languages-in-chromes-implementati
// //de-DE en-GB fr-FR en-US en-AU
// utterance.lang = "en-GB";
// speechSynthesis.speak(utterance);
// }
/* <option value="en-GB">GB</option>
<option value="en-US">US</option>
<option value="en-AU">AU</option>
<option value="fr-FR">FR</option>
<option value="de-DE">DE</option>
<option value="en-IN">IN</option>
<option value="zh-CN">CN</option>
<option value="pl">PL</option>
<option value="ru">RU</option>
<option value="sv-SE">SE</option>
<option value="en-ZA">ZA</option> */
// The API also allows you to get a list of voice the engine supports:
// speechSynthesis.getVoices().forEach(function(voice) {
// console.log(voice.name, voice.default ? voice.default :'');
// });
// Then set a different voice, by setting .voice on the utterance object:
// var msg = new SpeechSynthesisUtterance('I see dead people!');
// msg.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == 'Whisper'; })[0];
// speechSynthesis.speak(msg);