You are browsing as a guest. Sign up (or log in) to start making projects!

f

@f

Joined June 27th, 2026

  • 21Devlogs
  • 4Projects
  • 3Ships
  • 45Votes
Open comments for this post

6h 12m 10s logged

Zephyr Devlog #3 :rupnil-devlog:

This week started with a pretty simple plan: add streaming static files, implement HTTP range requests, and optimise the metrics system I talked about in the last devlog.

All three landed, but while working on streaming I ended up finding one of the most interesting bugs in the project so far.

Streaming static files

Until now, Zephyr always loaded an entire file into memory before sending it. That is fine for small assets, but not for large downloads.

Static files now stream directly from disk, while cached files still come straight from memory. The cache behaviour hasn’t changed, but anything outside the cache no longer has to allocate the whole file first.

I also added support for HTTP range requests (206 Partial Content), including If-Range, so downloads can resume correctly instead of starting over.

The bug

Everything passed its tests, so I benchmarked it with a 256 MB file.

Memory usage was still growing almost linearly with the file size.

After a lot of testing I tracked it down to a single Hyper configuration option I enabled back in week one. It disabled the backpressure that streaming depends on, so the server buffered data as fast as the disk could read it instead of as fast as the client could receive it.

Removing one line changed peak memory usage from this:

256 MB file Peak RSS Old implementation 402 MB “Streaming” 240 MB Fixed 7.4 MB

The throughput difference on normal workloads was only around 1 to 4%, which is close to benchmark noise, but the memory improvement is massive. More importantly, it removes an easy denial of service case where slow clients could force the server to hold onto huge amounts of memory.

It was a good reminder that passing tests only proves the output is correct. It does not prove the implementation is efficient.

Faster metrics

The other big change was the metrics system.

Every request updates several counters. They were already sharded per thread, but I was still doing seven atomic fetch_add operations on every request.

Owned shards now use simple load/store operations instead, while shared shards still use atomics when they have to. That reduced the cost of recording metrics from about 26 ns to 3.5 ns, roughly a 7 to 8x improvement.

End to end, that translated into about a 10% throughput increase in the plaintext and cached static benchmarks.

Also changed

  • Target::File now streams instead of reading the whole file into memory.
  • Cached files now reuse pre-built ETag headers instead of recreating them for every request.
  • Added 13 new tests covering streaming, range requests, 416, If-Range, and the metrics changes.
  • Removed every source code comment from the project.

Next

  • Finally get the benchmark suite running against PostgreSQL on Linux.
  • Add large file workloads to the benchmark suite.
  • Look into reusable buffers for the streaming path.
  • Continue work on the async plugin ABI.

The biggest lesson this week was that benchmarks need to measure more than correctness. The streaming implementation passed every test, but it was not actually streaming.

0
0
12
Open comments for this post

7h 52m 41s logged

Zephyr Devlog #2 :blobhaj_sunglasses: :blahaj:

Yesterday I published my first Zephyr devlog with a list of things I wanted to tackle next: better WebSocket support, more realistic benchmarks, and measuring RAM. I expected it to be a few small improvements, but it ended up becoming a much bigger project than I thought.

A lot of this update isn’t just adding features. It involved redesigning parts of the benchmark suite, reworking parts of the server to support more realistic workloads, fixing bugs I only discovered while building those workloads, and making a number of performance improvements along the way. There were a lot of small technical decisions and trade-offs behind the scenes that took far longer than I expected.

The biggest change was throwing away the old benchmark suite entirely. It did its job, but it wasn’t measuring the kinds of workloads that real applications actually run. If I wanted Zephyr’s benchmarks to mean something, I needed to build a new suite from the ground up that tested real-world scenarios instead of just the HTTP layer. Anyways, the benchmarks are below, you can go check them out, where Zephyr is consistently top 3 in all benchmarks.

0
0
61
Open comments for this post

4h 58m 15s logged

Zephyr Devlog #1 :yay:

This week I focused on getting the core of Zephyr working and making it as fast as possible.

What I built

  • Core HTTP server using Hyper
  • Router with support for static and dynamic routes
  • Static file serving
  • Plugin system
  • Metrics for tracking requests
  • Benchmark suite to compare Zephyr with other frameworks

Bugs I fixed

I found a few bugs while writing integration tests:

  • Body size limits weren’t always enforced.
  • If-None-Match headers weren’t working correctly.
  • The rate limiter rewrote some valid configs.

These were all fixed after writing more tests.

Performance

After benchmarking, I realised the server wasn’t using all CPU cores efficiently. I rewrote the threading model so each worker had its own runtime, which increased throughput by about 45%.

Current plaintext benchmark:

| Framework | Requests/sec |
| Zephyr | 321k |
| actix-web | 314k |
| Node.js (cluster) | 266k |

I’m happy that Zephyr is now competitive with one of the fastest Rust web frameworks.

Next

  • Better WebSocket support
  • Streaming static files
  • More realistic benchmarks (JSON, databases, uploads)
  • More plugin improvements
  • Benchmarking things like RAM usage too
    Overall I’m really happy with how the project is progressing. The biggest lesson this week was to benchmark before assuming something is the bottleneck.
4
0
70
Open comments for this post

6h 7m 19s logged

67 hours !!!!!!!!

This update was mainly about improving the web browser and fixing bugs I found across the OS.

The browser is now much more capable than before. I added a much better CSS engine, a lot more JavaScript features, proper form support with POST requests, cookies, animated GIFs, media placeholders, and lots of networking improvements. I also changed the homepage to DuckDuckGo Lite, so you can actually search the web from inside pefiaOS.

I also fixed several kernel bugs, including memory corruption issues, framebuffer bugs, safer memory management, more reliable timing, and network driver improvements.

Building the OS is easier now too. If you don’t have the cross compiler installed, it can now use your system GCC instead. I also improved VM compatibility by adding better diagnostics when booting with the wrong firmware.

There is still a lot I want to add, like UTF-8 support, certificate verification, paging, and user mode, but this is the biggest browser update pefiaOS has had so far.

0
0
36
Open comments for this post

15h 41m 32s logged

Devlog 05 - The Return: Giving pefiaOS a real kernel

This update was mostly focused on replacing a lot of the “fake OS” parts with real operating system infrastructure.

The biggest milestone was getting interrupts working. I added my own GDT, built an IDT with exception and IRQ handlers, remapped the PIC, programmed the PIT to 100 Hz, and implemented kernel threads with a handwritten x86 context switch. The scheduler is still cooperative because the heap and window manager aren’t thread safe enough for preemption yet, but background threads can finally run independently.

I also wrote an ATA PIO driver capable of reading and writing real IDE disks using LBA28 addressing. On top of that I rewrote the VFS into a writable, heap-backed filesystem, so applications can now create, modify and delete files instead of relying on a compile-time file table. Persistence is still missing, but FAT32 can now be built on top of the driver.

The desktop gained a lot of new functionality too. The code editor now supports syntax highlighting and line numbers, the terminal gained proper filesystem commands like mkdir, touch, rm, cat, echo > file, and ps, and I added both C and Python-style interpreters using the same recursive descent expression engine.

Graphics also received a major upgrade. The desktop now runs at 1920x1080 and I replaced the old 1-bit bitmap font with grayscale anti-aliased glyphs generated from Consolas. The renderer blends glyph coverage into the framebuffer, making text much easier to read without changing any existing layouts.

I also improved the desktop itself with window snapping, a scrollable Start menu, a live Settings app for themes and system settings, interactive browser text inputs, and a number of browser rendering improvements including larger page support and faster text drawing.

The hardest part was getting all these systems working together. Interrupts initially caused repeated triple faults because my descriptor tables were wrong, the scheduler had to coexist with the existing window manager, and changing the VFS meant updating almost every built-in application.

To make sure nothing regressed, I added a boot self-test that verifies the interpreter, writable VFS, scheduler, timer interrupts and ATA disk driver every time the OS starts.

Things I’d love people to test:

  • Open multiple windows and try snapping them around the desktop.
  • Use the terminal to create, edit and delete files.
  • Open the code editor and test syntax highlighting.
  • Try typing into browser text inputs.
  • Change the desktop theme and accent colour in Settings.

This update doesn’t add one huge feature, but it lays the groundwork for the next major milestones: paging, user-mode processes, ELF loading, and a persistent filesystem.

0
0
66
Ship Pending review

I made Breakdown, a privacy-first Chrome extension that turns giant Terms of Service and Privacy Policies into a quick, readable summary. One click gives you a risk score, the biggest red flags, what data is collected, your rights, and the clauses you should actually care about. The best part: everything runs locally on your device. No accounts, no API keys, no cloud, and no tracking.

The biggest challenge was making it accurate without relying on AI. My first version used a local LLM, but it was slow, huge, and sometimes confidently made things up. I replaced it with my own rule-based NLP engine that detects legal clauses, handles things like “we do not sell your data”, and shows the exact sentence that triggered each result.

I’m most proud that Breakdown became better by removing AI, it went from a 1-2GB model download to an instant 18KB offline analyzer. To test it, open any Terms of Service or Privacy Policy page, click the extension, and see what companies are actually asking you to agree to.

  • 4 devlogs
  • 37h
Try project → See source code →
Open comments for this post

6h 6m 53s logged

Bringing everything together

Today was mostly about merging all five feature branches back into main and making sure everything still worked afterwards. I also managed to speed up the summaries to near instant so the user experience is way better. (Screenshots are from Anthropic ToS)

Most of the merges happened automatically, but I still went through the UI files manually to make sure nothing had been overwritten and the new components all fit together properly.

New features

  • Radial risk gauge around the score.
  • Risk category breakdown card.
  • Background analysis using a Web Worker.
  • Faster debounced search.
  • Confidence chips and skeleton loading.

Final checks

After merging everything I:

  • Ran all 24 unit tests.
  • Built the extension from scratch.
  • Verified the worker bundled correctly.
  • Checked the UI for duplicate styles or merge issues.
  • Cleaned up the temporary branches and worktrees.

Everything passed, so the project is now back on a single branch with all five features fully integrated.

0
0
30
Open comments for this post

10h 35m 45s logged

Goodbye AI, hello NLP

This update completely changed how Breakdown works. The screenshots are from review of the Meta (Facebook) ToS and the Hack Club ToS, see if you can tell which one is which and comment it 😉

Originally it used a 1-2 GB language model running through WebLLM. It worked, but startup was slow, downloads were huge, and it could still hallucinate clauses that weren’t actually in a policy.

I replaced the entire pipeline with a deterministic rule-based NLP engine that runs fully on-device. I briefly kept a small embedding model to catch unusual wording, but testing showed it was responsible for almost every false positive, so I removed that too.

What changed

  • Removed all AI models and embeddings.
  • No downloads or GPU required.
  • Fully offline and deterministic.
  • Analyzer shrunk to just 18 KB.

Biggest challenge

The hardest part was keeping the results accurate without relying on AI. I rewrote detection around sentence-level rules, proper negation handling, and much stricter legal clause matching, then built a new test suite using real-world policies to make sure false positives stayed gone.

The result

  • Removed 49 npm packages.
  • Deleted the entire AI pipeline.
  • Faster analysis with no waiting.
  • More reliable results than the original AI version.
0
0
23
Open comments for this post

11h 38m 6s logged

bugs bugs bugs.

this devlog is just about bugs there were soooooooo many bugs

bug 1: ai models giving up - there were instances where the model timed out for one reason or another but didnt throw an error to the extension so you could’ve waited 20 minutes with the same loading screen..

bug 2: inaccuracies and hallucinations - with such a small AI model that runs locally, it isn’t as good as the latest ChatGPT or Claude, so the answers tended to be of a lower quality and sometimes just plain lies

feature add! : instead of a static loading screen there is now stages, with the word count of the summary also being updated in real time, with some added facts to keep the user interested!

next, i hope to improve model quality further and fix a bug where transformers.js/ONNX runtime is trying to cache a chrome-extension:// WASM URL leading to an error.

1
0
30
Open comments for this post

8h 40m 16s logged

I am working on a Chrome Extension called Breakdown.
What is Breakdown?
Breakdown is a Chrome Extension that summarises Terms of Services and Privacy Policies, so you can really see what companies are collecting from you.

My Progress so far:
I have made a working prototype, which has a 65% accuracy, with the categories being right like 50% of the time…

Struggles:
It was very difficult to get WebLLM working with a Local AI Model that didn’t frequently hallucinate but can still run on bad specs (no GPU, etc.)

To do:

  • Redo UI, i hate it so much
  • Try and add cool loading animations when downloading AI Models for first time
  • Make AI Model way more accurate
1
0
25
Open comments for this post

13h 18m 48s logged

More ways to break the cloth

This update was mostly about adding interactive features.

The biggest one was cloth tearing. My first attempt never actually worked because the strain limiter prevented springs from stretching far enough to snap. The fix was checking the stretch before the limiter ran, then making sure tearing also removed the connected shear and bend springs so pieces actually separated instead of hanging by invisible links.

I also added:

  • A throwable physics ball that transfers momentum into the cloth.
  • Mouse grabbing so you can pull and fling the fabric around.
  • A live tension heatmap to show where the cloth is under stress.
  • Slow motion (down to 1/8×) and frame-by-frame stepping for debugging.

The ball ended up being my favourite feature. Throwing it through a pinned curtain now rips a hole through the fabric, the stress heatmap lights up around the impact, and the cloth keeps simulating normally afterwards.

Everything was backed up with new self-tests for tearing and ball collisions, and the original cloth behaviour stayed identical when the new features were disabled.

0
0
28
Ship

What I made

FaceFall is a real-time 3D cloth simulator written in C99. It simulates cloth falling over spheres, cubes, and arbitrary OBJ meshes, with a live preview and deterministic MP4 export at up to 4K 120 FPS.

What was challenging

Getting the cloth to actually behave like fabric. Most of the work went into making the simulation stable while adding self-collision, realistic aerodynamics, and reliable mesh collision without particles tunnelling through geometry or the cloth exploding.

What I’m proud of

I’m most proud that it feels believable. You can change cloth resolution, material, wind, and colliders, then export smooth 120 FPS videos, all from a single C source file.

How to test it

Build with build.bat and run facefall.exe. I recommend using a 64×64 or 128×128 cloth, trying each collider, toggling self-collision, changing the fabric presets, and exporting a 120 FPS video with V. You can also run facefall –selftest to verify the physics automatically.

  • 4 devlogs
  • 24h
  • 13.74x multiplier
  • 310 Stardust
Try project → See source code →
Open comments for this post

8h 54m 25s logged

FaceFall - Devlog #3

Making the cloth actually feel like cloth

This update was all about making the simulation feel physically believable instead of just stable. Some things worked exactly as I’d hoped, some didn’t, and one bug ended up explaining why cloth doesn’t really bounce.

Better aerodynamics

The old simulation only used simple linear drag, which meant the whole cloth slowed down evenly in every direction. It worked, but everything fell like it was moving through syrup.

I replaced that with per-triangle aerodynamic forces. Every triangle now generates drag based on its orientation and velocity, so the cloth behaves much more naturally. A flat sheet catches the air like a parachute, while an edge-on sheet slices straight through it.

The drag is also normalised so changing the cloth resolution doesn’t completely change the way it falls.

The difference is surprisingly noticeable. Around the one second mark the cloth now billows into a canopy before landing, something the old solver never managed.

Self collision

Another thing I wanted was proper self collision.

Previously, folds could pass straight through each other. I implemented a spatial hash so nearby particles can efficiently detect overlaps without checking every possible pair, keeping the cost close to linear even on larger simulations.

The first time I tried self collision a while ago it was unstable because I only corrected positions. This time every collision also updates particle velocity, so the solver no longer fights itself.

Folded cloth now stacks into proper layers instead of collapsing through itself.

Softer collisions

I also rewrote the collision response.

Instead of instantly pushing particles outside the collider, objects now behave like spring-damper surfaces. The cloth compresses slightly into the collision shell before settling, which produces much smoother landings and completely removed the tiny jitter I was previously working around.

The bounce bug

This ended up being the most interesting part of the update.

I originally wanted the cloth to bounce realistically, so I tried several different approaches. None of them looked right.

While debugging I found something strange. After impact, some particles still had positive upward velocity for frame after frame, yet they never actually moved.

The culprit was strain limiting.

Every correction was changing particle positions without updating their velocities, meaning momentum was effectively disappearing from the simulation. Once I applied the matching velocity correction alongside each positional fix, impacts started travelling naturally through the cloth as visible waves instead of vanishing.

Ironically, fixing that bug also answered the original question.

Real cloth barely bounces.

Once the sheet starts draping over a sphere, the hanging fabric absorbs almost all of the remaining energy. Even with perfect restitution the cloth only lifted a few centimetres before settling again.

Because of that, the default fabric presets now use very low restitution values. Silk barely rebounds at all, while leather keeps a little more energy.

Higher frame rate

The simulator now runs internally at 120 FPS.

Preview mode still displays at 60 FPS by stepping the simulation twice per frame, while exports run at the full rate. Renders take longer, but the smoother motion is absolutely worth it, especially during impact.

Current state

This update made the simulation feel much closer to real fabric.

The cloth now catches the air properly, folded layers no longer pass through each other, collisions are smoother, and the behaviour after impact looks far more convincing than before.

It also reminded me that sometimes the most realistic result isn’t the one you expect. After spending hours trying to make the cloth bounce, the correct answer turned out to be that real cloth… mostly doesn’t.

0
0
14
Open comments for this post

2h 1m 48s logged

Going back to basics

After trying a few more “realistic” cloth techniques, I realised I’d made the simulation worse instead of better.

The biggest problems were all my own:

  • Self-collision pushed overlapping particles apart in position space without changing their velocity, so the springs immediately snapped them back and the whole cloth could launch itself across the scene.
  • Replacing bend springs with angle constraints made the cloth feel soft and unstable because the position-based constraints were fighting the force-based spring solver.
  • Per-triangle aerodynamic forces changed the way the cloth fell and settled, but not for the better.

Sometimes the simplest solution really is the right one.

I rolled the simulator back to the model that was already producing the best results:

  • Structural, shear, and bend springs
  • Per-particle wind
  • Linear air drag
  • Strain limiting as the only position correction

I removed self-collision and the angle-based bending entirely. Fabric presets now just adjust the bend spring stiffness, so materials like silk and leather still behave differently without adding unnecessary complexity. The settings menu was cleaned up to match.

The rendering improvements all stayed, including the updated shader, high-resolution offscreen exports (1080p, 1440p and 4K), and the quality-of-life improvements to the presets and UI.

I also added a --selftest mode that automatically runs a standard cloth drop onto the sphere and checks that the simulation stays stable. It verifies that particle positions remain finite, the cloth doesn’t explode or fling itself away, and structural springs stay within the configured strain limit.

0
0
10
Open comments for this post

1h 36m 8s logged

FaceFall — Devlog #2

2026-07-04 — The cloth was invisible the whole time

This update started with one simple bug report:

“the cloth barely renders and it keeps clipping into the model.”

It turned out to be three completely different problems.

By the end of today I’d rebuilt the renderer, rewritten parts of the collision system, doubled the maximum cloth resolution to 128x128, added adjustable cloth and collider sizes, and accidentally made the entire simulation explode into NaNs.

The invisible cloth

At first I assumed the renderer or lighting was broken.

It wasn’t.

The real problem was raylib’s batching. I disabled backface culling before submitting the cloth geometry, but re-enabled it before the batch was actually flushed to the GPU. The simulation itself was perfectly fine, but almost the entire cloth was getting backface-culled before it ever reached the screen.

The fix was simply flushing the render batch before and after changing the GPU state so the cloth was actually drawn with culling disabled.

While I was there I also rewrote the lighting. Instead of flat shading per quad, the cloth now generates smooth per-vertex normals and uses simple Gouraud shading. The difference is huge, especially on higher resolutions.

The clipping bug

The second issue was much harder.

The first problem was that my collision shell was far too thin. At lower resolutions the particles stayed outside the collider, but the rendered surface between them could still cut straight through the mesh. I fixed that by scaling the collision shell with particle spacing so coarse cloth stays slightly further away from the surface.

That solved part of it.

The bigger issue only showed up against thin meshes. Sometimes a particle could move completely through the object in a single step, and because the collision system only looked at the particle’s final position it would happily push it out of the wrong side.

The solution was switching to continuous collision detection. Every particle now stores its previous position, and I sweep that movement against the mesh instead of only checking where it ended up.

The explosion

My first implementation of continuous collision looked perfect.

For about three seconds.

Then the cloth completely disappeared.

It turned out I had created an energy feedback loop where particles bounced between both sides of thin geometry until the simulation exploded into NaNs.

Instead of pushing particles to a new position after a collision, I now simply restore their previous valid position and remove the inward velocity. It’s slightly more conservative, but completely stable.

Bigger simulations

With collision working properly again I increased the maximum cloth resolution from 64x64 to 128x128.

That pushed the simulation to over 16,000 particles, nearly 100,000 springs, and roughly 32,000 rendered triangles.

To keep performance reasonable I added a simple spatial grid for mesh collisions so particles only test nearby triangles instead of the entire mesh every substep.

The result is still effectively real-time, even at the highest resolution.

New settings

The settings menu also picked up a couple of new options:

  • Adjustable cloth size
  • Adjustable collider size

Changing either one rebuilds the simulation immediately, updates the collision data, and automatically reframes the camera so everything stays visible.

Current state

FaceFall is finally starting to feel like a proper tool rather than just a physics demo.

The renderer looks significantly better, collisions are much more reliable, larger simulations run comfortably, and exporting deterministic comparison clips is now almost entirely hands-off.

There’s still plenty left to do, especially around self-collision, but it’s getting much closer to the project I originally imagined.

1
0
13
Open comments for this post

11h 15m 22s logged

Dev Log #1 - FaceFall

I started FaceFall because I kept seeing those short videos where a cloth drops over the same object at different mesh resolutions, but I don’t know how to use things like Blender to make them myself. The difference between a 2x2 sheet and a dense mesh is surprisingly satisfying, and I wanted to build my own version from scratch instead of relying on an existing physics engine.

The goal isn’t just to make another cloth simulator. The mesh density is the whole point. At really low resolutions the cloth behaves more like a stiff piece of cardboard, while higher resolutions start producing proper folds, ripples, and believable draping.

Reference: https://www.youtube.com/shorts/s_G2gBbWYF0

What’s working

So far I’ve built a complete cloth simulator in a single C99 source file using raylib.

Current features include:

  • Mass-spring cloth simulation
  • Structural, shear, and bending springs
  • Hooke’s law with damping
  • Semi-implicit Euler integration
  • Runtime cloth resolutions from 2x2 up to 64x64
  • Sphere, cube, and arbitrary OBJ mesh colliders
  • Three application modes:
    • Settings
    • Live preview
    • Deterministic render/export
  • Direct ffmpeg export to MP4

At this point it’s less of a physics experiment and more of a small content creation pipeline. I can recreate the exact same simulation with different resolutions and export identical camera angles for comparison videos.

Challenges

The biggest challenge early on was stability. Increasing spring stiffness quickly caused the simulation to explode, so I ended up basing the number of simulation substeps on the spring frequency instead of using a fixed timestep.

The cloth also stretched far too much at first and looked more like rubber than fabric. Adding strain limiting made a huge difference and stopped the structural springs from over-extending.

Collision was easily the hardest part. Spheres and cubes weren’t too bad, but arbitrary OBJ meshes became a rabbit hole of closest-point tests, broad-phase checks, collision response, and trying to stop particles tunnelling straight through thin geometry.

I also spent longer than I’d like fighting Windows. Exporting raw frames through ffmpeg would randomly corrupt the output until I realised _popen needed to be opened in binary mode.

Current bug

The biggest thing I’m still working through is sphere collision.

Most of the time it behaves exactly how I’d expect, but every now and then parts of the cloth clip into the sphere instead of settling over the surface. Once a few particles end up inside the collider the cloth starts rendering incorrectly, so it’s pretty obvious when it happens.

I’m fairly confident the issue isn’t the spring solver anymore. The collision detection itself is finding the contacts, but the positional correction isn’t always pushing particles completely back outside the sphere. That’s the main thing I want to fix before moving on.

What’s next

Once the collision is reliable I want to polish the visuals and start generating comparison clips at different mesh densities.

That’s really the whole reason I started this project. Seeing the exact same cloth drop change from a rigid, blocky sheet into something that actually looks like fabric is surprisingly satisfying, and now I finally have a tool that lets me create those videos however I want.

0
0
9
Open comments for this post

12h 50m 48s logged

Devlog — Snake, Breakout, a Smarter Shell, and Build Hygiene

This week I added two new games (Snake and Breakout, bringing the total to seven), expanded the shell with new built-ins and command history, and cleaned up the build system. Everything boots and runs in QEMU.

Snake

The ring buffer approach makes movement O(1) instead of O(n):

uint16_t s_body[SN_CAP];        /* ring buffer of cell indices */
int      s_head, s_len;

Input and movement run on separate clocks. Input latches every 33 ms, movement every 130 - 4×score ms (minimum 60 ms). This way no keypresses drop and difficulty scales naturally.

The grid is 16 pixel cells, clamped to window size. Apples spawn via rejection sampling. Filling the entire board wins the round.

Breakout

26.6 fixed point physics handles shallow angles that integer pixels would quantise to zero. Paddle english depends on where you hit it:

int off = bx - g->k_px;
g->k_bvy = -g->k_bvy;
g->k_bvx = (off << 6) / (pw / 6);

Ball starts stuck to the paddle, launches with Space. Three lives, then game over.

Integration

Adding two games touched almost no window-manager code. Two enum entries in games.h, two lines per dispatch switch in games.c, and the Start menu entry in taskbar.c. The WM handles everything else automatically.

Shell Improvements

Added five new built-ins: free, uptime, history, ver, and fixed echo to print blank lines. Terminal got uptime too.

One Version String

#define PEFIA_VERSION "pefiaOS 0.3 (Stardance)"

All three places that display version now build from this single define.

Build Fixes

Fixed header dependency tracking:

CFLAGS += -MMD -MP
-include $(OBJS:.o=.d)

Editing a header now correctly rebuilds only the objects that include it. Cleaned up boot.asm trailing whitespace too.

Testing

Verified in my virtual machine: both games launch and play correctly, Terminal shows the new version string, all shell commands work.

Seven games on a kernel I wrote from scratch!! :D

0
0
36
Ship Pending review

Overview

pefiaOS is a bare metal 32-bit x86 operating system written entirely from scratch in C and NASM. It contains around 9,000 lines of kernel code with no libc or third party kernel code.

Features

  • Graphical desktop with overlapping windows, taskbar, Start menu, and window manager
  • Complete networking stack (Ethernet, ARP, IPv4, ICMP, UDP, DHCP, DNS, TCP)
  • TLS 1.3 implementation from scratch for real HTTPS support
  • Web browser with HTML rendering and inline image support
  • Five built in games including Flappy Bird, Pong, Tetris, a Mario style platformer, and a Wolfenstein style raycaster
  • Runs the original 1993 DOOM through PureDOOM inside a desktop window

Challenges

Some of the more difficult parts of the project included:

  • Writing TLS 1.3 and its cryptographic primitives entirely from scratch
  • Building a complete TCP/IP networking stack without timer interrupts
  • Implementing DEFLATE, JPEG, and BMP decoders by hand
  • Running everything in a cooperative single threaded kernel
  • Integrating the real DOOM engine into a freestanding bare metal environment

Highlights

I’m especially proud that pefiaOS isn’t just a toy kernel. It can browse the real web over HTTPS, run a full graphical desktop, play games, and even run the original DOOM, all on hardware with no host operating system, no libc, and no runtime underneath.

Running pefiaOS

After building the cross compiler, simply run:

make
make run

Or boot pefiaOS.iso in VirtualBox using an Intel PRO/1000 network adapter.

Things to try

  • Browse a real HTTPS website
  • Play one of the built in games
  • Launch DOOM from the Start menu
  • Open the terminal and run about
  • Capture network traffic with make run-net

Current limitations

  • No audio support yet
  • TLS does not verify server certificates
  • No preemptive multitasking
  • No JavaScript engine

The part that still feels surreal is watching the OS boot, opening the browser, and loading real HTTPS websites from the internet on an operating system I built entirely from scratch.

  • 3 devlogs
  • 7h
Try project → See source code →
Open comments for this post

1h 19m 38s logged

Bringing Games (and DOOM) to pefiaOS

This update was all about making pefiaOS capable of running real time applications. The desktop was originally designed around event driven apps, so games needed quite a bit of work before they were even possible.

What’s new?

  • Off screen rendering to eliminate flickering
  • Proper held key input for responsive controls
  • Fixed timestep game loop
  • Resizable game windows
  • Flappy Bird
  • Pong
  • Tetris
  • Mario style platformer
  • Wolfenstein style 3D raycaster

Once those were working, I had to answer the obvious question: can it run DOOM? It turns out it can. I integrated PureDOOM by writing a platform layer that hooks the engine into my own memory allocator, timer, input system, framebuffer, and virtual filesystem. Since there’s no disk driver yet, the shareware WAD is embedded directly into the kernel, meaning DOOM now runs inside a normal desktop window on pefiaOS itself. Seeing the real 1993 DOOM running on an operating system I built from scratch has easily been one of the most rewarding moments of the project so far, and it also kinda shows that it can do something cool too, not just boring kernels and such.

0
0
29
Loading more…

Followers

Loading…