Learning Jam

March 15-17. March 22-24.
In 22 days.
March 15-17.
March 22-24. In 22 days.
Learn more

We are working to correct the course of the software industry.

We are a community of low-level programmers with high-level goals. Originally inspired by Casey Muratori's Handmade Hero, we dig deep into our systems and learn how to do things from scratch. We're not satisfied by the latest popular language or the framework of the month. Instead we care about how computers actually work.

Software quality is declining, and modern development practices are making it worse. We need to change course. Help us get the software industry back on track.

Latest News

I'm pleased to write this final news post of the year together with Abner Coimbre!

Dear Handmade Community,

Warm holiday greetings! Abner Coimbre and Ben Visness here, teaming up to announce that the Handmade Cities Matrix server will remain online permanently. In past years, it has been shut down at the end of conferences, but now it will remain active year-round!

This might surprise you, since most of you are probably already members of the (now rather large) Handmade Network Discord server. So why keep the Matrix server as well?

The Handmade movement has grown an incredible amount in the past several years. Importantly, it has grown both online and in the real world. Both domains are vital to the health of the larger Handmade community - but there are some critical differences between the two. Let's dive into it.

Two communities? Not quite.

The Handmade Network (HMN) is the online hub for the Handmade movement. Led by Ben and his team, they run programming jams, Twitch shows, and online social gatherings. They provide a place for community members to discuss programming, learn from each other, and share what they're working on. The Handmade Network is also the home of Handmade projects, including the Orca initiative and Abner's own Terminal Click.

In essence, HMN is the online community - and it's accessible to everyone, including those who prefer to remain anonymous.

Handmade Cities (HMC) brings the Handmade movement into the physical realm. Headed by Abner and his own staff, HMC orchestrates tech conferences like Handmade Boston and Handmade Seattle, which are venues to present to the rest of the world our software and ideals. HMC also organizes monthly in-person meetups worldwide.

In essence, Handmade Cities is all about in-person events. HMC emphasizes real-world interactions; by its very nature, those who participate in these events can't be anonymous!

For several years now, Handmade Cities has used a Matrix server for discussions related to conferences and conference meetups. This server has always complemented the Handmade Network Discord server, rather than competing with it. And that is not going to change!

The HMN Discord remains open to all, while users on the HMC Matrix are tied to real individuals participating in Handmade events: ticket holders, local meetup members, and so on. The Discord is the hub for jams and other online events; the Matrix is the hub for meetups and other in-person events.

What about Handmade Hero? How's that going?

At the start of the Handmade movement was Handmade Hero, a Twitch series showing how to craft a video game from scratch. Casey Muratori, president of Molly Rocket, started it in November 2014 and quickly found great success, forming a huge community around its values that has lasted almost a decade.

So, what's become of our bouncy little friend? Casey's passions have expanded beyond this project, reflecting Molly Rocket's commitment to multiple initiatives. We're not privy to the specifics of Casey's plans with Handmade Hero, but this year, we collaborated directly with him to shape the opening blurbs for both Handmade Network and Handmade Cities:


Originally inspired by Casey Muratori's Handmade Hero, we dig deep into our systems and learn how to do things from scratch. We're not satisfied by the latest popular language or the framework of the month. Instead we care about how computers actually work.


Inspired by Handmade Hero

Like Handmade Hero by Molly Rocket we believe in breaking software down to the bare bones and building back an understanding of how it all really works.

While Molly Rocket, Handmade Network, and Handmade Cities share a spirit of mutual support, it's crucial to emphasize that we exist as separate entities, and are not formally affiliated. You might instead see us as independent stewards of the Handmade movement.

And at the end of the day, that's the way we like it. We each have our own expertise, our own experiences, our own goals, and ultimately our own businesses. We feel that we're at our best, and the Handmade movement is at its best, when we are run independently but collaborate at every opportunity.

We look forward to bringing you improved conferences, jams, meetups, shows, and projects in 2024. With our 10-year anniversary fast approaching (!) the future of Handmade shines brighter than ever. 😊

All the best,

Abner and Ben

Around the Network

New blog post: C3 0.5.4 is out!
Christoffer Lernö

It's been about one month since C3 0.5.3 (announcement) was released. Since then there has been quite a lot of non-breaking additions to the compiler and I'm happy to announce the release of 0.5.4 of the C3 programming language. (Grab the downloads here: https://github.com/c3lang/c3c/releases/tag/v0.5.4)

In terms of changes to the language, bitstructs have gotten some additional love, with == and != supported and bit operations on bitstructs are now folded at compile time for constant bitstructs.

Startup initialization / finalization for macOS got an overhaul and is now guaranteed to be ordered, despite the OS not supporting ordering. This finally made dynamic calls safe to use with init functions.

For the stdlib, memory functions are changing. The family of new functions are now zero initializing by default. The reason is subtle: with implicit zeroing of locals, it's natural to start assuming everything is zero by default, even with heap allocations. So having mem::new being non-initialized is the wrong default, the new convention is that new means zeroing allocation and alloc means non-zeroing allocation. So all the functions ending with "zero" and "clear" are deprecated in favor of just the default new.

Also, similarly how stream methods like file.printf(...) was abandoned for io::fprintf(file, ...), the many allocator methods are getting deprecated for removal in 0.6. To replace this, std::mem::allocator is getting malloc, free, new and other functions that take an allocator.

Some examples:

int* x = mem::new_zero(int);
int* y = mem::new(int);
// replaced by:
int* x = mem::new(int);
int* y = mem::alloc(int);

Foo* f = my_allocator.new(Foo);
// replaced by:
Foo* f = allocator::new(my_allocator, Foo)

It might seem counterintuitive that allocator::new is preferable given that it's longer. However, it turns out it's much easier to work with than methods for a consistent set of functions to call.

In any case, most applications should prefer standard heap and temp allocations using the functions in std::mem.

Finally there's the addition of the experimental "GenericList", which is a tentative name. It can hold a heterogenous list of objects. The downside is that it requires more memory management as it's based around any*.

Changes / improvements

  • Hash variables may now take a designated initializer.
  • Added @safemacro to override the @ requirement for non-function-like macros.
  • More information available with debug log in non debug builds.
  • Removed install_win_reqs.bat which didn't work well.
  • Support ** to mean ./**
  • MacOS init/finalizer now respects priority.
  • Bitstructs supports != and ==.
  • Support Windows .def files using --windef.
  • Bitstructs now fold compile time constant bit ops.
  • Fix issue where in some cases a constant global with a string wasn't folded (e.g. in asm stmts)
  • Lateral implicit imports removed.
  • Default to '.' if no libdir is specified.
  • Improved error messages for --lib.
  • Added --linker to set the linker #1067.


  • Fixes to macro context evaluation with macro varargs.
  • Dynamic methods registered before init functions on MacOS.
  • Fixed clobber on x86 cpuid instruction.
  • Removed invalid syntax from grammar.y.
  • output project setting now respected.
  • Aliased declarations caused errors when used in initializers.
  • Aliased consts used as constant initializers caused errors.
  • Exported module names replace :: by _.
  • Const ternary would evaluate incorrectly for ?:
  • $$MODULE would report the incorrect module name in macros.
  • Fixed debug info for globals and for/switch scopes.
  • out now correctly detects subscript[] use.
  • Ambiguous recursive imports are now correctly detected.
  • Overzealous local escape check corrected #1127.
  • Fixes to the matrix functions #1130.

Stdlib changes

  • Deprecated Allocator helper functions.
  • Added mem::allocator functions corresponding to removed allocator functions.
  • Changed mem::new / mem::temp_new to accept an optional initializer, and will clear by default.
  • Mem _clear and _zero variants deprecated. "new_*" functions will clear by default.
  • Mem "alloc_" functions replace old "new_" behaviour.
  • Fixed temp memory issue with formatter.
  • Added temp_push and temp_pop for pushing / popping the temp allocator manually (or from C).
  • Added byte_size to List
  • Added GenericList.

0.5 has feature stability guarantees, so any code written for 0.5.0 will with on all of 0.5.x.

If you want to read more about C3, check out the documentation: https://c3-lang.org or download it and try it out: https://github.com/c3lang/c3c

Christoffer Lernö

An observation: I notice that by virtue of people being mostly anonymous, a curious effect occurs on programming discords (and by extension elsewhere):

People who are "chat savvy" (or whatever we should call being good at writing in a way that is similar to being good at social interactions in real life) are able to dominate discussions by virtue of this.

In addition, people tend to "cluster" when it comes to opinions, so that followers of such persons may sway others ("everyone else agrees on this").

However, such savvy has nothing to do with actual programming skill or knowledge. Many of these "leaders" are in fact fairly inexperienced, if not outright beginners. Age is similarly obfuscated, so that teenagers might be seen as old and middle-aged persons may be taken for teenagers.

The most obvious example when someone new comes to a Discord and enthusiastically starts presenting ideas. If these ideas are not "approved" by the leaders, the person might immediately be mocked and treated as a beginner / idiot.

I've seen this played out several times, at one occasion a 60+ year old gentleman presenting a language and compiler, where he solved several long standing practical problems he'd encountered over the course of his career. He was laughed at and ridiculed as knowing nothing about programming or real world problems by kids 1/3rd his age because he wasn't presenting it in the way that was "expected" in that community. It was painful to see.

Outside of direct bullying, criticizing well-known people in the business is a favorite past-time. You often find people confidently deriding others as "not having any experience", "not knowing what they're talking about", "is just making things up etc". These critics are very sure of themselves, with aforementioned followers to echo those feelings. So you end up with a bunch of 16-year olds deriding 50+ year old programmers with multiple hit games under their belt as "not knowing anything about programming" and collecting pats on the back by the crowd for saying something so profound!

So what is my point? Nothing really except for these observations and to conclude that there is no wisdom of the crowds online, you need to find truth on your own.

New forum thread: Support for x86 executables
New forum thread: Tile/Grid based movement?
New forum thread: RemedyBG

Community Showcase

This is a selection of recent work done by community members. Want to participate? Join us on Discord.