Wisedocks

Behind the Scenes: The Making of Code Breaker

Behind the Scenes: The Making of Code Breaker
Published on: June 20th, 2025
Last updated: June 21st, 2025

Building Code Breaker

I spent the first few days this week working on Baby Launcher; specifically wresting with the damn <canvas> element to scale properly on any screen. It was driving me mad. 

The Crypto Puzzle has been a pain to size properly as well, so I decided to start over from scratch with a new game. I needed a fresh perspective to tackle the problem.

Enter: Code Breaker. It's a trivia game built completely in a <canvas> element, it features the Matrix style rain inspired by my Echo Chamber Effect project, and will fit all screens easily. At least, that's the end game. I'm basically combining everything learned in the last few months into one project.

All the games on this site use a universal popup modal for scores. This time, I wanted to go a different direction and build everything right into the canvas. This time; no outside popups, no extra UI, and perfect scaling on every device.

Fullscreen Headache

Right now, I've settled on grabbing the screen size dynamically with JavaScript and setting the canvas size accordingly. It seems to be working fine. It took way longer than I will admit to build these 3 functions.

function updateHeaderHeightVar() {
    const header = document.querySelector('header.header');
    const headerHeight = header ? header.offsetHeight : 0;
    document.documentElement.style.setProperty('--header-height', `${headerHeight}px`);
}
window.addEventListener('DOMContentLoaded', updateHeaderHeightVar);
window.addEventListener('resize', updateHeaderHeightVar);

function resizeCanvasToWindow() {
    const canvas = document.getElementById('gameCanvas');
    const header = document.querySelector('header.header');
    const headerHeight = header ? header.offsetHeight : 0;

    if (isFullscreen()) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        canvas.style.marginTop = '0';
    } else {
        const rect = canvas.getBoundingClientRect();
        canvas.width = rect.width;
        canvas.height = rect.height;
    }
}

window.addEventListener('resize', resizeCanvasToWindow);
window.addEventListener('DOMContentLoaded', resizeCanvasToWindow);


function goFullscreen() {
    let el = canvas;
    if (el.requestFullscreen) el.requestFullscreen();
    else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();
    else if (el.msRequestFullscreen) el.msRequestFullscreen();
    setTimeout(resizeCanvasToWindow, 100);
}

I'm sending the --header-height var to CSS to determine the height. I keep forgetting you can send JavaScript to CSS.

The sad part is, I still have a long road ahead in this area. Need to hide the full screen button entirely for Safari browser and make the button (not shown here) work both ways.

canvas#gameCanvas {
  display: block;
  margin: 0;
  padding: 0;
  width: 100vw;
  height: calc(100vh - var(--header-height, 100px));
}

The game is starting to feel alive, despite there being tons of features still to go. For now, this feels like a good stopping point for the week. Time to document progress and start this post, which will double as a changelog as I keep going. If all goes well, Code Breaker will hit the homepage early next week. If I don't break the code.

To Do List

  • Rebuild the full screen functions. Hide on Safari because it doesn't support full screen API (Get with the times, Apple), and make the full screen button work both ways to escape full screen.
  • Add an in-game notification to rotate the screen on small phones. The game still looks very smooshed in portrait mode, I don't think I can get it much better.
  • Redesign the "New" button. It's not intuitive and can be confusing. If you get stuck on a question you can grab a new one but it deducts 10 points. It needs a better flow. Maybe add a timer and if the user gets stuck on a question for more than 10 to 15 seconds, highlight the button or shake it. Easy fix with mouseover on PC; nightmare on phones.
  • Add tons of more questions for replay value. 
  • Modularize the JavaScript into different files. (The scrolling up and down, back and forth in one main file is hurting my eyes.)
  • Add more sound effects.
  • Add High scores in game.

Changelog

June 21st, 2025

  • Built the end game modal screen and added some confetti for fun.
  • Added to homepage as the game is at least functional now.

June 20th, 2025

  • Worked on full screen functions (see above).
  • Removed all toast notifications and put them into the feedback element on canvas.
  • Moved score submission modal into the canvas and styled it for the game.
  • Added background music, and a few sound effects.
  • Built the mute button logic. Set a flag in local storage to remember users setting.

June 19th, 2025

  • Built out basic functions for submitting scores to the database
  • Built out a dummy event handler so I can capture screen clicks to trigger functions.
  • Removed dummy event handler because I'm a dummy, and put keydown/mousedown events into the DOM with event listeners.
  • Added the new button so if you get stuck on a question, you can get a new one.
  • Built the PHP function files to grab questions and check answers server-side. This keeps people from cheating to some degree.

June 18th, 2025

  • Setup database and added some questions.
  • Rebuilt the Matrix rain background by refactoring the code from my Echo Chamber Effect website.
  • Got basic functions like level, score, answers, and feedback working.
  • Started building the game.
<< Previous

Related Posts

Building The Baby Launcher Game

Building The Baby Launcher Game

Decipher This: Crypto Puzzle Arrives at Wisedocks

Decipher This: Crypto Puzzle Arrives at Wisedocks