Building CenterOS: Making a Fake OS Game With Nothing But JavaScript, One Canvas, And Too Much Ambition

Published: 05/12/2025

Play CenterOS

Around three weeks ago, I learned JavaScript. Not the mythical “I’ve been doing JS for 10 years” JavaScript, not the React ecosystem, not servers, not bundles, nothing. I mean literally: “Open canvas, draw Pac-Man, eat pellets.” That level. Simple stuff. Fun! Then I made Tetris. Also fun.

And then with no transition my brain decided: “What if we build a full fake operating system inside a canvas? And what if it has police databases, WiFi cracking, an underworld market, a live case management system, a trace meter, random officers going on and off duty, a notepad app, buttons, terminals, clickables, and a bunch of nonsense that makes the browser act like it's a suspicious device from a horror game?”

I didn’t plan any of this. I just said yes to the impulse. What follows is a breakdown of how CenterOS works underneath. Not as some grand engineering feat, but as a surprisingly coherent mess of small JavaScript parts working together. Everything here runs in a single canvas. No HTML UI frameworks. No external libs. Just classes, objects, and the update/render cycle I learned in class three weeks ago.


CenterOS Philosophy: “Fake it until it feels real”

A huge part of the magic in games like Scrutinized and Welcome to the Game is that the computer itself feels alive. The OS lies to you. The network lies to you. You type something and the machine reacts in its own strange rhythm. You’re not clicking menus you’re peeking into someone else’s digital world.

CenterOS is my attempt to reach that feeling using very small tools:

The point wasn’t to be realistic, the point was to feel like an OS with a personality.


The Loop: The Heartbeat of CenterOS

Everything runs through one loop defined in loop.js. It’s not async, not promise-based. Just a fixed timestep:

function tick(now) {
    const delta = now - lastTime;
    accumulator += delta;

    while (accumulator >= frameDuration) {
        update(dt);
        accumulator -= frameDuration;
    }

    render();
    requestAnimationFrame(tick);
}

This loop calls:

And that’s truly it.
A simple loop.
Everything alive in CenterOS breathes in that heartbeat.


The OS Layer: Where Windows, Apps, and Input Pretend to Be a Real OS

windowManager.js handles:

appRegistry.js is basically “installed apps” a lookup table of classes that can be launched.

state.js stores persistent things:

This is all extremely lightweight. No file I/O, no backend. It’s basically a pretend operating system built from arrays and objects.


Apps: Buttons, Terminals, Windows, and Chaos

I originally thought I’d make only terminal-based apps. But I lied to myself. Because I ended up making:

For example, caseManagerApp.js has literal buttons you can click with the mouse, arranged in a grid, drawn onto the canvas.

Meanwhile, NetHackerApp.js is full terminal simulation; scrolling lines, command parsing, and “fake typing” behavior.

And apps like telScannerApp.js mix text scanning output with clickable UI.

The reason this works is because every app follows the same structure:

The OS doesn’t care whether you’re a terminal, or a button grid, or a scanner, or a database viewer. It just pipes events to the currently active window.

That’s what gives CenterOS the “everything feels integrated” vibe.


The Terminal: Just an Array of Strings and a Dream

The terminal in CenterOS looks alive but is actually dead simple. It’s literally:

this.lines = [];
this.input = "";
this.maxLines = 150;

When you type:

The rendering is literally:

ctx.fillText(line, x, y)

Line by line.
No fancy animations.
The feel comes from pacing how often messages appear, delays, formatting.


The World: Making Fake Humans Behave Worse

This is where the "game" part sneaks in. caseWorld.js generates:

Every officer has:

networkManager.js takes the networks from the officers and displays them as hackable WiFi networks.

citizenDbApp.js lets you look up people involved in cases.

caseManagerApp.js ties everything together you solve cases by coordinating the tools in other apps.

It’s all very small and simple, but when combined, it feels like you’re hacking into a tiny simulated world.


Hacking: Timers, Fake Progress Bars, and No Async

Most people assume hacking simulations use timers, promises, delays, async code, etc. CenterOS does not.

It’s all done in update(dt) via state machines.

For example, WiFi cracking:

On every frame, I simply do:

job.elapsed += dt;
job.tries += job.triesPerSecond * dt;

if (job.elapsed >= job.duration) {
    completeCrack();
}

That’s it.
No async/await.
No setTimeout.
The world only progresses because the loop keeps ticking.


Buttons & Clickable UI

Quite a few apps have clickable UIs:

These are just rectangles tested with:

if (x >= rect.x && x <= rect.x + rect.w &&
    y >= rect.y && y <= rect.y + rect.h) {
    // clicked inside this button
}

And then I draw them with:

ctx.fillRect(...);
ctx.fillText(...);

This makes the UI feel like an actual OS with multiple interaction styles, not just a text-only shell.


The Trace System: The Thing Trying To Kill You If You Can Die

traceManager.js is the part that whispers: “You should not be doing that.”

Every suspicious action raises trace. Some hacks spike it. Some apps lower it. The atmosphere manager flashes warnings. Everything ties back into the loop.

There’s nothing mathematically complicated here just numbers, thresholds, and events. But your brain interprets it as danger.


Atmosphere: Shakes, Alerts, and “Something Is Wrong” Hopefully

atmosphereManager.js is small but very effective:

It turns raw mechanics into vibes.


What I Learned From Accidentally Building an OS

The biggest lesson: Small pieces scale surprisingly far when they talk to each other cleanly.

I didn’t reinvent operating systems. I just stitched together:

And because each piece stayed simple, the whole thing stayed understandable to a point.

I also learned that you don’t need advanced frameworks to make something feel bigger than it is (beginner talking here). A canvas, a few rectangles, and some text can create an entire imaginary machine if you lean into the limitations.

CenterOS is not a “big” project by professional standards. But for me, three weeks into learning JS it taught me more about architecture, state, and simulation than any tutorial ever could.

And honestly? It was just for an impulse that made me lose sleep over days where I just hated JavaScript. But it was worth it at the end. I hate you Script of Java.


← Back to list