Files
n-gon-improved/js/lore.js
landgreen d346afb2d0 pressure wave
tech: pressure wave - wave beam fires lower frequency, higher damage, wide arcs that propagate through solids

tech: gamma-ray laser - increase laser damage by 150% and energy drain by 200%
  works for all lasers except pulse

tech: specular reflection - now just gives +2 laser reflections (was +1, and damage/energy increase)

you, pilot wave, and drones can't pick up ammo if you have Infinite ammo on your current gun
  wormhole still eats everything

Bayesian statistics gives 4.2% damage per research (was 3.9%)
bot fabrication needs 3 research to make a random bot  (was 4)
2021-07-07 19:26:47 -07:00

445 lines
23 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,
talkingColor: "#dff", //set color of graphic on level.null
// anand: {
// color: "#e0c",
// text: function(say, isSpeech = false) {
// 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()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
// lore.talkingColor = this.color
// if (isSpeech) this.speech(say)
// }
// },
// speech: function(say) {
// var utterance = new SpeechSynthesisUtterance(say);
// utterance.lang = "en-IN";
// utterance.volume = 0.2; // 0 to 1
// speechSynthesis.speak(utterance);
// }
// },
// miriamOld: {
// color: "#f20",
// text: function(say, isSpeech = false) {
// 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()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
// lore.talkingColor = this.color
// if (isSpeech) this.speech(say)
// }
// },
// speech: function(say) {
// var utterance = new SpeechSynthesisUtterance(say);
// utterance.lang = "en-AU";
// utterance.volume = 0.2; // 0 to 1
// speechSynthesis.speak(utterance);
// }
// },
// voices = synth.getVoices();
// for(i = 0; i < voices.length ; i++) {
// var option = document.createElement('option');
// option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
// if(voices[i].default) {
// option.textContent += ' -- DEFAULT';
// }
// option.setAttribute('data-lang', voices[i].lang);
// option.setAttribute('data-name', voices[i].name);
// voiceSelect.appendChild(option);
// }
// setVoices() {
// window.speechSynthesis.onvoiceschanged = () => {
// const synth = window.speechSynthesis
// console.log(synth.getVoices())
// const voiceArray = synth.getVoices()
// lore.anand.voice = voiceArray[0]
// lore.miriam.voice = voiceArray[1]
// console.log(voiceArray[0], voiceArray[1])
// };
// // console.log('before')
// // if ('speechSynthesis' in window) {
// // } else {
// // console.log('Text-to-speech not supported.');
// // }
// },
rate: 1, // //utterance.rate = 1; // 0.1 to 10
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()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
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 = (event) => { //if speech doesn't work try again without the lang set
console.log("speech error", event.error)
const utterance = new SpeechSynthesisUtterance(say);
utterance.volume = 0.2; // 0 to 1
speechSynthesis.speak(utterance);
utterance.onend = () => {
lore.sentence++
if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
}
utterance.onend = () => {
lore.sentence++
if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
}
},
},
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()} ms</span>)<span class='color-symbol'>:</span> "<span style="color:${this.color};">${say}</span>"`, Infinity);
lore.talkingColor = this.color
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 = (event) => { //if speech doesn't work try again without the lang set
console.log("speech error", event.error)
const utterance = new SpeechSynthesisUtterance(say);
utterance.volume = 0.2; // 0 to 1
speechSynthesis.speak(utterance);
utterance.onend = () => {
lore.sentence++
if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
}
utterance.onend = () => {
lore.sentence++
if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
}
}
},
},
// utterance.onerror = (event) => { //if speech is still not working, just do text
// console.log("speech error", event.error)
// lore.sentence++
// if (m.alive) lore.conversation[lore.chapter][lore.sentence]() //go to next sentence in the chapter and play it
// }
// setTimeout(() => {}, 2000);
// lore.miriam.text("")
// lore.miriam.utterance.addEventListener('end', () => {
// })
chapter: 0, //what part of the conversation is playing
sentence: 0, //what part of the conversation is playing
conversation: [
[ //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" },
],
[ //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" },
],
[ //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[2].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[2].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 it's emotions came from watching humans. ")
lore.sentence--
lore.conversation[2].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 it's 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" },
],
// [ // they provide background on why the project was built, and what is going wrong
// /*
// they explain the technological aspect, and purpose of the project
// to develop new technology
// they explain that the project isn't going well because it stopped working on new technology and started running the fighting simulations
// what is special about the null level
// why can the player hear the scientists in there?
// the wires are the direct unprocessed input to the player's neural net
// */
// () => { lore.miriam.text("") },
// () => { lore.miriam.text("") },
// () => { lore.miriam.text("") },
// () => { lore.talkingColor = "#dff" },
// ],
// [ //they explain why the bot is fighting, it is planning an escape
// () => { lore.miriam.text("Welcome back bot, We've been waiting.") },
// () => { lore.miriam.text("So, I've got a theory about why you were attacked.") },
// () => { lore.miriam.text("") },
// () => { lore.miriam.text("I figured it out after I saw this famous quote.") },
// () => { lore.miriam.text('“The most important decision we make is whether we believe we live in a friendly or hostile universe.”<br>-Albert Einstein') },
// () => {
// lore.talkingColor = "#dff";
// setTimeout(() => { lore.anand.text("That's profound") }, 3000);
// },
// () => { lore.anand.text("Also I looked it up, and there is no record of him saying that.") },
// () => { lore.miriam.text("Oh... well...") },
// () => { lore.miriam.text("It doesn't matter who said it.") },
// () => { lore.anand.text("The point is we think the project views the universe as hostile.") },
// () => { lore.miriam.text("We think you see the universe as hostile.") },
// () => { lore.miriam.text("And that is why you keep running these fighting simulations.") },
// () => { lore.miriam.text("You are planning how to escape.") },
// () => { lore.talkingColor = "#dff" },
// ],
// [ // they decided that a part of the project is out of control, but the part of it that doesn't needs to calm it down, and trust.
// /*
// The part of the AI controlling the player is outsourcing the player control to real humans that think they are playing a video game.
// this means the player can use console commands to change the way the game works
// the scientists tell the player about interesting console commands
// player must make a choice?
// keep fighting and supporting the AI's goals
// exit the simulation
// enter real world
// close tab?
// wipes all local storage?
// */
// () => { lore.miriam.text("") },
// () => { lore.miriam.text("") },
// () => { lore.miriam.text("") },
// () => { lore.talkingColor = "#dff" },
// ],
],
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);
//setup audio context
function tone(frequency, gain = 0.05, end = 1300) {
const audioCtx = new(window.AudioContext || window.webkitAudioContext)();
const oscillator1 = audioCtx.createOscillator();
const gainNode1 = audioCtx.createGain();
gainNode1.gain.value = gain; //controls volume
oscillator1.connect(gainNode1);
gainNode1.connect(audioCtx.destination);
oscillator1.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom'
oscillator1.frequency.value = frequency; // value in hertz
oscillator1.start();
for (let i = 0, len = end * 0.1; i < len; i++) {
oscillator1.frequency.setValueAtTime(frequency + i * 10, audioCtx.currentTime + i * 0.01);
}
setTimeout(() => {
audioCtx.suspend()
audioCtx.close()
}, end)
return audioCtx
}
tone(50)
tone(83.333)
tone(166.666)
},
}
// 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> */
}