๐ŸŽฎArcadeLab

Midnight Muse

by BlazingTurtle39
929 lines21.4 KB
โ–ถ Play
<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1">

<title>Midnight Muse</title>

<style>

*{box-sizing:border-box}

body{margin:0;background:#100b18;color:#f7eaff;font-family:Georgia,serif}

header{text-align:center;padding:22px 10px;background:linear-gradient(#352044,#100b18)}

h1{color:#e5b5ff;letter-spacing:4px;font-size:clamp(28px,7vw,44px);margin:8px}

header p{color:#c5a9d8;letter-spacing:2px;font-size:12px}

main{max-width:850px;margin:auto;padding:12px}

.panel{background:#1d1428;border:1px solid #68477e;border-radius:18px;padding:18px;margin-bottom:14px}

h2{color:#e5b5ff}

h3{color:#f3d5ff}

button{font:inherit;cursor:pointer;touch-action:manipulation}

.btn{width:100%;padding:13px;margin:6px 0;border-radius:12px;border:1px solid #8d60a6;background:#342143;color:#fff;text-align:left}

.btn:hover{background:#503260}

.primary{background:#d5a0ed;color:#1a0e23;text-align:center;font-weight:bold;border:0}

.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}

.item{padding:12px 4px;min-height:78px;border:1px solid #69477e;background:#291c37;color:white;border-radius:12px;font-size:12px}

.item span{display:block;font-size:27px;margin-bottom:5px}

.item.selected{border:2px solid #e6b8ff;background:#4c315f}

.scene{text-align:center;background:radial-gradient(circle,#4a2c5a,#1b1227 75%);border-radius:15px;padding:18px;margin:12px 0}

.art{font-size:44px;letter-spacing:5px}

.muted{color:#c7b1d6;font-size:13px;line-height:1.6}

.stats{display:flex;justify-content:space-between;gap:8px;flex-wrap:wrap;color:#f5d38a;font-size:13px}

.progress{height:7px;background:#3b2948;border-radius:10px;margin:12px 0;overflow:hidden}

#bar{height:100%;width:0;background:#d7a0f2}

input{width:100%;padding:12px;background:#100b18;color:white;border:1px solid #805c96;border-radius:10px}

.badge{display:inline-block;border:1px solid #8d60a6;padding:6px 9px;margin:3px;border-radius:15px;color:#e5b5ff;font-size:12px}

footer{text-align:center;color:#9f88af;font-size:12px;padding:16px}

@media(min-width:650px){.columns{display:grid;grid-template-columns:1fr 1fr;gap:12px}}

</style>

</head>

<body>

<header>

<div style="font-size:30px">โ˜พ โœฆ ๐Ÿฆ‡ โœฆ โ˜ฝ</div>

<h1>MIDNIGHT MUSE</h1>

<p>THE SECRET OF RAVEN CASTLE</p>

</header>

<main>

<div class="panel">

<div class="stats">

<span>๐Ÿช™ Coins: <b id="coins">100</b></span>

<span>๐Ÿ“– Chapter: <b id="chapter">1</b>/6</span>

<span>๐Ÿ”Ž Clues: <b id="clues">0</b></span>

</div>

<div class="progress"><div id="bar"></div></div>

<div id="screen"></div>

</div>

<div class="columns">

<div class="panel">

<h3>๐Ÿ“œ Story Journal</h3>

<div id="journal" class="muted">Your story begins tonight.</div>

</div>

<div class="panel">

<h3>๐Ÿ† Your Collection</h3>

<div id="collection" class="muted"></div>

<button class="btn" onclick="wardrobe()">๐Ÿ‘— Open Wardrobe</button>

<button class="btn" onclick="achievements()">๐Ÿ† Achievements</button>

<button class="btn" onclick="save()">๐Ÿ’พ Save Progress</button>

</div>

</div>

<footer>Every outfit tells a story. Every secret has a price. ๐Ÿ–ค</footer>

</main>

<script>

const $=id=>document.getElementById(id);

const chapters=[

["A Letter After Midnight","๐ŸŒ™ ๐Ÿ•ฏ๏ธ ๐Ÿฅ€","A black envelope arrives at your door. Inside is a silver key and a note: Come to Raven Castle before the final bell. Someone there knows the truth about your family."],

["The Forgotten Castle","๐Ÿฐ ๐ŸŒซ๏ธ ๐Ÿ—๏ธ","The gates close behind you. A portrait has vanished from the wall. Footsteps echo upstairs, although the caretaker claims nobody has visited in years."],

["The Midnight Atelier","๐Ÿ‘— ๐Ÿชก ๐Ÿ’Ž","Behind a hidden door, you discover an abandoned fashion studio. The legendary designer Seraphina disappeared on the night of the last royal ball."],

["The Mysterious Guest","๐Ÿ–ค ๐Ÿ•ฏ๏ธ ๐Ÿ—ก๏ธ","A mysterious guest named Lucien recognizes your silver key. He offers to help uncover the truth. But can you trust him?"],

["The Midnight Ball","๐Ÿ•ฏ๏ธ ๐Ÿ‘‘ ๐Ÿฅ€","The ballroom opens for one night. Everyone wears a mask. Somewhere among the dancers is someone hiding the truth."],

["The Last Secret","๐ŸŒ‘ ๐Ÿ“œ ๐Ÿ”ฎ","Behind the portrait chamber, you discover a locked box containing a letter that changes everything you believed about Raven Castle."]

];

const outfits=[

["๐Ÿ–ค","Raven Velvet",0],["๐Ÿ’œ","Violet Dream",20],

["๐Ÿฅ€","Rose of Night",25],["๐Ÿฆ‡","Vampire Royalty",35],

["๐Ÿ‘‘","Moonlit Queen",50],["๐ŸŒ™","Celestial Shadow",60],

["๐Ÿ•ธ๏ธ","Spider Silk",30],["โœจ","Starlight Gothic",45],

["๐Ÿฉถ","Silver Phantom",40],["๐ŸŒน","Crimson Rose",35],

["๐Ÿชป","Lavender Witch",25],["๐Ÿ’Ž","Crystal Duchess",70]

];

const hairs=[

["๐Ÿ–ค","Raven Hair",0],["๐Ÿ’œ","Violet Hair",10],

["๐ŸŒ‘","Shadow Hair",15],["๐Ÿค","Silver Hair",20],

["โค๏ธ","Crimson Hair",20],["๐ŸŒ™","Moon Hair",25]

];

const accessories=[

["๐Ÿฆ‡","Bat Brooch",0],["๐Ÿ—๏ธ","Silver Key",10],

["๐Ÿ’Ž","Dark Jewels",20],["๐Ÿ‘‘","Midnight Crown",30],

["๐Ÿฅ€","Black Rose",15],["๐Ÿ•ท๏ธ","Spider Pendant",15]

];

const backgrounds=[

["๐Ÿฐ","Raven Castle",0],["๐ŸŒฒ","Haunted Forest",10],

["๐ŸŒ•","Moon Garden",15],["๐Ÿ•ฏ๏ธ","Secret Library",20],

["๐ŸŒŒ","Starless Sky",25]

];

function fresh(){

return {

name:"Muse",chapter:0,coins:100,clues:[],

unlocked:["Raven Velvet","Raven Hair","Bat Brooch","Raven Castle"],

outfit:"Raven Velvet",hair:"Raven Hair",

accessory:"Bat Brooch",background:"Raven Castle",

personality:"detective",trust:0,romance:0,choices:[],

rooms:[],achievements:[],ending:"",dressed:false,

judged:false,ballChoice:""

};

}

let S=fresh();

function esc(v){

return String(v).replace(/[&<>"']/g,c=>({

"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"

}[c]));

}

function save(silent=false){

try{

localStorage.setItem("midnightMuseSave",JSON.stringify(S));

if(!silent)alert("Progress saved on this device! ๐Ÿ–ค");

}catch(e){

if(!silent)alert("Saving isn't supported here, but you can keep playing!");

}

}

function load(){

try{

const old=JSON.parse(localStorage.getItem("midnightMuseSave"));

if(old&&Array.isArray(old.unlocked)&&Array.isArray(old.clues))

S={...fresh(),...old};

}catch(e){}

}

function stats(){

$("coins").textContent=S.coins;

$("chapter").textContent=Math.min(S.chapter+1,6);

$("clues").textContent=S.clues.length;

$("bar").style.width=(S.chapter/6*100)+"%";

$("journal").innerHTML="<b>"+esc(S.name)+"</b><br>"+

(S.choices.length?S.choices.map(esc).join("<br>"):"No decisions recorded yet.")+

(S.clues.length?"<hr>๐Ÿ”Ž "+S.clues.map(esc).join("<br>"):"");

$("collection").innerHTML=

"๐Ÿ‘— "+S.unlocked.filter(n=>outfits.some(x=>x[1]===n)).length+"/"+outfits.length+" outfits<br>"+

"๐Ÿ’‡ "+S.unlocked.filter(n=>hairs.some(x=>x[1]===n)).length+"/"+hairs.length+" hairstyles<br>"+

"๐Ÿ† "+S.achievements.length+" achievements";

save(true);

}

function frame(title,body){

$("screen").innerHTML="<h2>"+title+"</h2>"+body;

stats();

}

function btn(text,fn,primary=false){

return '<button class="btn '+(primary?"primary":"")+'" onclick="'+fn+'">'+text+'</button>';

}

function addClue(name,description){

if(!S.clues.includes(name)){

S.clues.push(name);

S.coins+=10;

S.choices.push("Discovered: "+name);

}

}

function itemIcon(type,name){

let list=type==="outfit"?outfits:type==="hair"?hairs:

type==="accessory"?accessories:backgrounds;

let found=list.find(x=>x[1]===name);

return found?found[0]:"โœจ";

}

function home(){

frame("โœฆ Welcome to Raven Castle โœฆ",

'<div class="scene"><div class="art">๐Ÿฐ ๐ŸŒ™ ๐Ÿฅ€</div>'+

'<h3>Your story begins at midnight</h3>'+

'<p>Fashion ยท Mystery ยท Choices ยท Secrets</p></div>'+

'<p>A mysterious letter has summoned you to Raven Castle. Create your identity, explore secret rooms, meet mysterious characters, and discover the truth.</p>'+

'<label>Your character name</label><input id="playerName" maxlength="18" placeholder="Enter your name" value="'+

esc(S.name==="Muse"?"":S.name)+'">'+

'<h3>Choose your personality</h3>'+

btn("๐ŸŒน Romantic โ€” follow your heart","personality('romantic')")+

btn("๐Ÿ—๏ธ Detective โ€” investigate everything","personality('detective')")+

btn("๐Ÿ‘‘ Ambitious โ€” claim your destiny","personality('ambitious')")+

btn("๐ŸŒ™ Begin your adventure","startStory()",true)+

(S.chapter>0?btn("โ†ฉ Continue saved story","intro()",true):""));

}

function personality(p){S.personality=p;home()}

function startStory(){

const n=$("playerName").value.trim();

if(n)S.name=n;

S.chapter=0;S.coins=100;S.clues=[];S.choices=[];

S.rooms=[];S.trust=0;S.romance=0;S.ending="";

S.dressed=false;S.judged=false;S.ballChoice="";

S.unlocked=["Raven Velvet","Raven Hair","Bat Brooch","Raven Castle"];

S.outfit="Raven Velvet";S.hair="Raven Hair";

S.accessory="Bat Brooch";S.background="Raven Castle";

S.achievements=[];

intro();

}

function intro(){

if(S.ending){ending();return}

if(S.chapter>=6){finalMystery();return}

const c=chapters[S.chapter];

frame("CHAPTER "+(S.chapter+1)+" โ€” "+c[0],

'<div class="scene"><div class="art">'+c[1]+'</div>'+

'<h3>'+c[0]+'</h3><p>'+c[2]+'</p></div>'+

'<p><b>Mission:</b> Complete the chapter and collect clues.</p>'+

btn("Enter Chapter "+(S.chapter+1)+" โ†’","chapterAction()",true));

}

function chapterAction(){

switch(S.chapter){

case 0:gate();break;

case 1:explore();break;

case 2:fashion();break;

case 3:lucien();break;

case 4:ball();break;

case 5:finalMystery();break;

}

}

/* CHAPTER 1 */

function gate(){

frame("Chapter 1: The Silver Key",

'<div class="scene"><div class="art">๐Ÿ—๏ธ โœ‰๏ธ ๐ŸŒ™</div>'+

'<p>Which part of the mysterious envelope do you inspect first?</p></div>'+

btn("๐Ÿฅ€ The black rose seal","gateClue('Rose Seal','The rose matches a symbol on your family ring.')")+

btn("๐ŸŒ™ The moon drawing","gateClue('Moon Seal','Six tiny stars form a map around the moon.')")+

btn("๐Ÿ”‘ The silver key","gateClue('Silver Key','The key is warm, as if someone just held it.')"));

}

function gateClue(name,desc){

addClue(name,desc);

frame("The Castle Gate",

'<div class="scene"><div class="art">๐Ÿฐ ๐Ÿšช ๐Ÿฆ‡</div>'+

'<p>'+desc+'</p><p>The gatekeeper asks why you have come.</p></div>'+

btn("Tell him the truth","gateChoice('truth')")+

btn("Pretend you were invited to the royal ball","gateChoice('bluff')")+

btn("Ask about the missing portrait","gateChoice('portrait')"));

}

function gateChoice(v){

if(v==="truth"){S.trust++;S.choices.push("Told the gatekeeper the truth")}

if(v==="bluff"){S.coins+=10;S.choices.push("Bluffed your way inside")}

if(v==="portrait")addClue("Missing Portrait","The portrait was taken to the locked west wing.");

S.chapter=1;intro();

}

/* CHAPTER 2 */

function explore(){

const rooms=[

["๐Ÿ•ฏ๏ธ","Library","library"],["๐Ÿชž","Mirror Hall","mirror"],

["๐ŸŒน","Rose Garden","garden"],["๐Ÿ”’","West Wing","west"],

["๐ŸŽน","Music Room","music"],["๐Ÿ—๏ธ","Secret Stairs","stairs"]

];

frame("Chapter 2: Explore Raven Castle",

'<p>Visit the rooms and collect their clues. You can explore multiple rooms!</p>'+

'<div class="grid">'+rooms.map(r=>

'<button class="item" onclick="room(\\''+r[2]+'\\')"><span>'+r[0]+

'</span>'+r[1]+(S.rooms.includes(r[2])?" โœ“":"")+'</button>'

).join("")+'</div>'+

btn("Continue to the Atelier โ†’","finishExplore()",true));

}

function room(id){

const data={

library:["Old Library","๐Ÿ“š","A torn page mentions Seraphina, the vanished designer.","Designerโ€™s Letter"],

mirror:["Mirror Hall","๐Ÿชž","A mysterious locket bears a silver crescent.","Mirror Locket"],

garden:["Rose Garden","๐Ÿฅ€","A note says: The coldest person may be protecting you.","Garden Note"],

west:["West Wing","๐Ÿšช","A locked door has a musical symbol carved into it.","West Wing Clue"],

music:["Music Room","๐ŸŽน","A music sheet contains the numbers 2, 4, and 1.","Musical Code"],

stairs:["Secret Stairs","๐Ÿ•ฏ๏ธ","Velvet thread leads to an abandoned fashion studio.","Velvet Thread"]

}[id];

if(!S.rooms.includes(id)){

S.rooms.push(id);addClue(data[3],data[2]);S.coins+=5;

}

frame(data[0],'<div class="scene"><div class="art">'+data[1]+

'</div><p>'+data[2]+'</p><span class="badge">Clue: '+data[3]+

'</span></div>'+btn("Explore another room","explore()")+

btn("Return to the main hall โ†’","finishExplore()",true));

}

function finishExplore(){

if(!S.rooms.includes("finished")){S.rooms.push("finished");S.coins+=20}

S.chapter=2;intro();

}

/* CHAPTER 3 */

function fashion(){

frame("Chapter 3: The Midnight Atelier",

'<div class="scene"><div class="art">๐Ÿ‘— ๐Ÿชก ๐Ÿ’Ž</div>'+

'<h3>Moonlit Elegance</h3><p>Create a look worthy of the royal judges.</p></div>'+

'<p>Choose outfits, hairstyles, accessories, and magical backgrounds. Earn coins to unlock more fashion!</p>'+

btn("Open the Royal Wardrobe","wardrobe()",true)+

btn("Judge my outfit","judge()",true));

}

function wardrobe(){

let body='<div class="scene"><div class="art">'+itemIcon("hair",S.hair)+' '+

itemIcon("outfit",S.outfit)+' '+itemIcon("accessory",S.accessory)+'</div>'+

'<h3>'+esc(S.outfit)+'</h3><p>๐Ÿช™ '+S.coins+' coins</p></div>';

[

["outfit","Outfits",outfits],["hair","Hairstyles",hairs],

["accessory","Accessories",accessories],["background","Backgrounds",backgrounds]

].forEach(([type,title,list])=>{

body+='<h3>'+title+'</h3><div class="grid">'+list.map(x=>

'<button class="item '+(S[type]===x[1]?'selected':'')+

'" onclick="wear(\\''+type+'\\',\\''+x[1]+'\\')"><span>'+x[0]+

'</span>'+x[1]+'<br>'+(S.unlocked.includes(x[1])?"OWNED":"๐Ÿช™ "+x[2])+

'</button>').join("")+'</div>';

});

body+=btn("Done styling โ†’","backWardrobe()",true);

frame("โœง The Royal Wardrobe โœง",body);

}

function wear(type,name){

const lists={outfit:outfits,hair:hairs,accessory:accessories,background:backgrounds};

const x=lists[type].find(i=>i[1]===name);

if(!x)return;

if(!S.unlocked.includes(name)){

if(S.coins<x[2]){alert("Not enough coins! Complete missions for more.");return}

S.coins-=x[2];S.unlocked.push(name);

}

S[type]=name;wardrobe();

}

function backWardrobe(){

if(S.chapter===2)fashion();

else if(S.chapter===4)ball();

else intro();

}

function judge(){

let score=45;

if(["Violet Dream","Moonlit Queen","Celestial Shadow","Starlight Gothic"].includes(S.outfit))score+=25;

if(["Dark Jewels","Midnight Crown","Silver Key"].includes(S.accessory))score+=15;

if(["Moon Garden","Starless Sky"].includes(S.background))score+=15;

S.dressed=true;S.judged=true;S.coins+=score>=80?50:25;

if(!S.achievements.includes("Fashion Icon"))S.achievements.push("Fashion Icon");

frame("The Atelier's Verdict",

'<div class="scene"><div class="art">'+itemIcon("hair",S.hair)+' '+

itemIcon("outfit",S.outfit)+' '+itemIcon("accessory",S.accessory)+

'</div><h3>'+esc(S.outfit)+'</h3><p>Fashion score: <b>'+score+'/100</b></p>'+

'<p>'+(score>=80?"The judges are enchanted by your mysterious elegance!":"The judges admire your look! Try more items for a higher score.")+

'</p></div><p>You earned coins. A mysterious invitation waits for you.</p>'+

btn("Continue to Chapter 4 โ†’","nextChapter()",true));

}

function nextChapter(){S.chapter++;intro()}

/* CHAPTER 4 */

function lucien(){

frame("Chapter 4: The Mysterious Guest",

'<div class="scene"><div class="art">๐Ÿ–ค ๐Ÿ•ฏ๏ธ ๐Ÿ“–</div>'+

'<h3>Lucien</h3><p>"You should not be here," he whispers. "But perhaps you are the only person who can discover what happened."</p></div>'+

btn("๐Ÿ’— Ask why he wants to help","lucienChoice('heart')")+

btn("๐Ÿ”Ž Ask about Seraphina","lucienChoice('clues')")+

btn("๐Ÿ—ก๏ธ Tell him you do not trust him","lucienChoice('cold')"));

}

function lucienChoice(v){

if(v==="heart"){

S.romance++;S.trust++;S.choices.push("Asked Lucien why he cares");

addClue("Lucienโ€™s Promise","Lucien promises to protect the truth.");

}

if(v==="clues"){

S.trust++;S.choices.push("Questioned Lucien about Seraphina");

addClue("Lucienโ€™s Secret","Lucien knew Seraphina before she disappeared.");

}

if(v==="cold"){

S.trust--;S.choices.push("Refused to trust Lucien");

addClue("Hidden Photograph","A photograph shows Lucien beside a woman with a silver crown.");

}

S.chapter=4;intro();

}

/* CHAPTER 5 */

function ball(){

frame("Chapter 5: The Midnight Ball",

'<div class="scene"><div class="art">๐Ÿ•ฏ๏ธ ๐Ÿ‘‘ ๐Ÿฅ€</div>'+

'<p>The ballroom is filled with masked guests. Your fashion might help you impress the nobles, blend into the crowd, or distract the host.</p></div>'+

btn("๐Ÿ‘— Change into a royal ball outfit","wardrobe()",true)+

btn("๐ŸŽญ Approach the masked host","ballChoice('host')")+

btn("๐Ÿ’ƒ Dance with Lucien","ballChoice('dance')")+

btn("๐Ÿ•ต๏ธ Search behind the curtains","ballChoice('search')"));

}

function ballChoice(v){

if(v==="host"){

addClue("The Hostโ€™s Crest","The host's crest matches the seal on your invitation.");

S.choices.push("Questioned the masked host");

}

if(v==="dance"){

S.romance++;S.trust++;

addClue("Dance Card","Lucien's dance card has Seraphina's initials.");

S.choices.push("Danced with Lucien");

}

if(v==="search"){

addClue("Hidden Invitation","The missing designer signed the secret invitation.");

S.coins+=15;S.choices.push("Searched behind the curtains");

}

S.ballChoice=v;S.chapter=5;intro();

}

/* CHAPTER 6 */

function finalMystery(){

frame("Chapter 6: The Last Secret",

'<div class="scene"><div class="art">๐Ÿ“œ ๐Ÿ”’ ๐ŸŒ™</div>'+

'<p>A locked box contains the final secret. Examine your evidence before choosing your answer.</p></div>'+

btn("๐Ÿ”Ž Read my collected clues","showClues()")+

btn("๐Ÿ—๏ธ Try the silver key","solve('key')")+

btn("๐Ÿชž Use the mirror locket","solve('mirror')")+

btn("๐Ÿ‘‘ Search for the missing crown","solve('crown')"));

}

function showClues(){

frame("Your Evidence",

'<p>Here are the clues you have discovered.</p>'+

(S.clues.length?S.clues.map(c=>'<span class="badge">'+esc(c)+'</span>').join(" "):"No clues yet.")+

btn("Return to the mystery","finalMystery()",true));

}

function solve(v){

if(v==="key")addClue("The Box Opens","Inside is a letter written by Seraphina.");

if(v==="mirror")addClue("The Mirrorโ€™s Message","The locket reveals a hidden family name.");

if(v==="crown")addClue("The Crownโ€™s Truth","The crown belongs to Raven Castle's forgotten heir.");

let score=S.clues.length+(S.trust>0?1:0)+(S.rooms.length>=4?1:0);

S.choices.push("Investigated the final secret using "+v);

frame("The Truth Revealed",

'<div class="scene"><div class="art">๐Ÿ•ฏ๏ธ ๐Ÿ“œ ๐Ÿฅ€</div>'+

'<h3>The Lost Designer</h3>'+

'<p>The letter reveals that Seraphina was not a villain. She hid the royal collection to protect the castle from someone who wanted its power.</p>'+

'<p>Your silver key belonged to her last apprentice โ€” your ancestor. But one final decision remains.</p>'+

'<p class="muted">Evidence gathered: '+score+'</p></div>'+

btn("๐Ÿ’— Stay with Lucien and protect the castle","endGame('together')")+

btn("๐Ÿ‘‘ Claim the crown and rule Raven Castle","endGame('queen')")+

btn("๐ŸŒ™ Reveal the truth and leave","endGame('truth')"));

}

function endGame(v){

S.ending=v;

if(v==="together")S.achievements.push("Guardian of Hearts");

if(v==="queen"){S.coins+=100;S.achievements.push("Queen of Raven Castle")}

if(v==="truth")S.achievements.push("Truth Seeker");

if(!S.achievements.includes("Mystery Solved"))S.achievements.push("Mystery Solved");

S.chapter=6;ending();

}

function ending(){

const data={

together:["๐Ÿ’— The Guardian Ending","You and Lucien protect Seraphina's collection. The castle becomes a refuge for those who need it, and trust becomes your greatest treasure.","Two guardians begin a new legend beneath the moon."],

queen:["๐Ÿ‘‘ The Queen Ending","You claim the crown and restore Raven Castle. The atelier reopens, the nobles bow, and your name becomes the castle's new legend.","The throne is yours. May your reign be wise."],

truth:["๐ŸŒ™ The Truth Seeker Ending","You reveal the hidden letters to the world. Seraphina's name is cleared, her collection returns to the people, and you leave the castle free.","The mystery ends, but another adventure awaits."]

}[S.ending];

if(!data){home();return}

frame("โœฆ THE END โœฆ",

'<div class="scene"><div class="art">'+data[0].split(" ")[0]+' ๐Ÿฐ ๐ŸŒ™</div>'+

'<h3>'+data[0]+'</h3><p>'+data[1]+'</p><p><i>'+data[2]+'</i></p></div>'+

'<h3>Your Final Fashion Look</h3><div class="scene"><div class="art">'+

itemIcon("hair",S.hair)+' '+itemIcon("outfit",S.outfit)+' '+

itemIcon("accessory",S.accessory)+'</div><p>'+esc(S.name)+' ยท '+

esc(S.outfit)+' ยท '+esc(S.background)+'</p></div>'+

'<p>Clues: '+S.clues.length+' ยท Coins: '+S.coins+' ยท Achievements: '+S.achievements.length+'</p>'+

btn("๐Ÿ’Œ Share my story","shareStory()",true)+

btn("โ†ป Play again","resetGame()"));

}

function achievements(){

frame("๐Ÿ† Achievements",

'<div class="scene"><div class="art">๐Ÿ† โœจ ๐Ÿฆ‡</div><p>Your achievements</p></div>'+

(S.achievements.length?S.achievements.map(a=>'<span class="badge">โœฆ '+esc(a)+'</span>').join(" "):

"<p>Keep playing to unlock achievements!</p>")+

btn("Back to the story","intro()",true));

}

async function shareStory(){

const txt="I played Midnight Muse: Raven Castle! ๐Ÿ–ค My ending: "+S.ending+

". My style: "+S.hair+", "+S.outfit+", "+S.accessory+". Can you solve the mystery?";

try{

if(navigator.share)await navigator.share({title:"Midnight Muse",text:txt,url:location.href});

else prompt("Copy and share your story!",txt+"\n"+location.href);

}catch(e){if(e.name!=="AbortError")prompt("Copy your story!",txt)}

}

function resetGame(){

if(!confirm("Start a new story? Current progress will be replaced."))return;

S=fresh();

try{localStorage.removeItem("midnightMuseSave")}catch(e){}

home();

}

load();

if(S.ending)ending();else if(S.chapter>0)intro();else home();

</script>

</body>

</html>

Game Source: Midnight Muse

Creator: BlazingTurtle39

Libraries: none

Complexity: complex (929 lines, 21.4 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: midnight-muse-blazingturtle39" to link back to the original. Then publish at arcadelab.ai/publish.