Hacker Newsnew | past | comments | ask | show | jobs | submit | s-macke's commentslogin

Yes, you haven’t tried it. LLMs are actually awesome at deobfuscation, but terrible at obfuscation. They just can’t do it yet.

They also lack the creativity needed for those entries. Obfuscation is only one part of it. Coming up with the idea is another. Many entries also have special qualities that make them true works of art.


They should train on some of my colleagues code - they have an inate skill of turning anything simple and clear into a mindboggling mess

Lol you're so much smarter, nice

> They just can’t do it yet.

Have you tried it or are you guessing this?


Yes, I’ve tried it. For example, this was my winning entry from a year ago [0]. The LLM only performs trivial obfuscation, not advanced transformations.

For example:

  if (x == 1 || x == 2) { ...
can be transformed into:

  if (!(2+x*x-3*x)) { ...
An LLM will do this if you explicitly ask it to, but not on its own.

[0] https://github.com/ioccc-src/winner/blob/master/2024/macke/p...


One of the main instruments of obfuscation (and the way to get more out of the size constraints) is making the code as short as possible, so in that example you'd prefer

    if (!(x/2-1)) { ...
EDIT: Oops, confused the original with x==2 || x==3. Instead, we can use !(x-1>>1), which precedence rules parse as !((x-1)>>1).

I checked this in an online C-compiler and it is not equivalent to x==1 | x==2.

this statement is equivalent to x==2 | x==3.

For example, x=3, 3/2 = 1 then 1-1 = 0 so that !(0) is 1 or true. Also for x=1, 1/2 = 0 then 0-1 = -1 and !(-1) = 0 or false.

I agree with your point in general though about size constraints.


It's pretty easy to see what that does though, even if it is shorter. Wouldn't the other approach be more obfuscated?

extrano84 already found some errors but also 0 will fail and if x is int (instead of unsigned int) all negative numbers will also fail (but so will the original s-macke obfuscation as well).

Not sure what you mean by advanced transformations but I got these versions from ChatGPT without explicit instructions.

  if(x-1<2&&x)...
  if((1<<x)&6)...
  if(x<3&x)...
  if(3%x&&x<3)...
  if(!((x-1)*(x-2)))
  if(!(x^1|x^2))...
  if(!(x*x-3*x+2))

(1) fails for negative numbers

(2) fails for (x % 32 in [1, 2]) due to UB

(3) fails for x == 2

(4) crashes for x == 0

(5) is the same polynomial, only factorized

(6) always returns 0

(7) is the same polynomail reordered

But this works for any value of x:

  x<2==2-x
or for something shorter:

  x<3&x>0
but that's not bery obfuscated

But then we all know that LLM has come a long way since one year ago.

Are you sure they still can't do it?


Just two months ago I tried to write a short K code with Claude Opus 4.6, only to find that while it had sufficient knowledge about K vocabularies it didn't try to make good use of them. K is, while slightly obscure and obfuscated, a real programming language and certainly better known than obfuscated programming. I don't have high hope for IOCCC-grade obfuscation.

My favorite is the 366-byte C program emulator that can run Linux and Doom [0]. The VM implements an OISC - a One Instruction Set Computer [1].

[0] https://github.com/ioccc-src/winner/blob/master/2025/cable/p...

[1] https://github.com/ioccc-src/winner/blob/master/2025/cable/R...


Wow! And it also implements a very interesting variant of SUBLEQ that is turing complete.

>This VM implements an OISC - a One Instruction Set Computer. That instruction takes three signed 32-bit operands, a, b and c, and runs a program from memory m[] as follows:

1 PC (program counter) starts at 0

2 Fetch the next instruction (32-bit signed operands a, b and c)

3 If the low bit on any operand is set, remove it, and replace that operand with m[operand] i.e., a dereference of that address

4 Set m[b] = m[b] - m[a]

5 If m[b] is 0 or negative, set the PC to c, otherwise increment PC by 3 words

6 Go to step 2


> 3 If the low bit on any operand is set, remove it, and replace that operand with m[operand] i.e., a dereference of that address

This dereference option makes a second instruction, this is not OISC.


I've spent the past few weeks coming up with my own simple programming language, which compiles to linux/amd64 assembly.

I could have gone all out writing standard library routines for opening files, running shell commands, coding strstr, strcpy, and similar. And to be honest I did implement some things I didn't need as part of the learning process (for example print(getenv("HOME")) works). But I soon realized I needed some example programs to test things and show off.

So of course the first real program I implemented was a brainfuck interpreter. Which means my language is now, indirectly, turing complete!

My early versions took 9 minutes to output the famous mandelbrot program, so I had to make a bunch of optimizations, and later implemented support for switch/case statements to speed things up. Now I can generate the same output in two minutes - so room for improvement, but also a good bit of progress!

Cheating by implementing another language in my own was very very satisfying. Though of course this is all for fun/learning and not intended to be used seriously by anybody, not even myself!

https://github.com/skx/s-lang


Nice! What surprised my about the IOCCC submission though was how fast it ran. Sure, subleq can at least do some useful arithmetic in one instructions, but it still requires a lot of instructions to do an integer multiplication, let alone a floating point operation. But DOOM was actually playable with a decent FPS.

I think I like this idea, but the linked-to Eternal Software Initiative [1] is a bit confusing. There are several different versions of the instructions to decode this, all conflicting.

There's the one here: Set m[b] = m[b] - m[a]

Then it links to the reference implementation on github [2] which says you just need the napkin notes [3], which is dividing everything read by 4, which is corroborated by the reference implmentation [4], but it's not clear why 4 is chosen here rather than 2, as it seems to waste a bit. Was this bit needed, or is it reserved for future expansion?

I presume the original implementation didn't do the divide by 4 and it was added later, but I don't see why it was needed, other than perhaps just making LLVM code gen a little easier. I'd need to work through lots of examples to work out if the system as described is impossible without dividing by 4 (although you'd presumably only be able to access even addresses, and the PC increases by 3 each time, so it would definitely be annoying to refer to code locations).

Then the reference implementation starts doing magic when location 64 is accessed, overwriting locations 64-67 with the current time, which is mentioned in the napkin description, but not the description on the main page.

Both descriptions mention the magic -1 address, so it seems strange that the very implementation-dependent UTC clock isn't also implemented with -ve addresses rather than trashing memory that is otherwise free for the implementation to use as desired.

Both descriptions also mention the regular timer interrupt process, which also seems disappointing, reusing address 0 as the interrupt handler location and 1 as the saved PC, which means that you have to overwrite the initial entry point at location 0 as soon as the program starts.

[1] https://eternal-software.org/

[2] https://github.com/adriancable/eternal

[3] https://github.com/adriancable/eternal/blob/main/docs/napkin...

[4] https://github.com/adriancable/eternal/blob/main/vm/vm.c


Maybe answering my own question, but I'm now wondering if the reason that the divide by 4 was chosen (so essentially using byte addressing instead of word addressing) is so that the linker can do symbol fixup / relocation.


I downloaded and built this, and I feel confident in stating that this is the most impressive thing I have ever seen.

What I find fascinating is the fact that you can implement those few lines in an esoteric language such as FRACTRAN or Game of Life and even boot Linux on them. Seems doable now. In theory.

This VM implements an OISC - a One Instruction Set Computer.

More information:

https://github.com/ioccc-src/winner/blob/master/2025/cable/R...


Because I haven't found the special case in the disassembly for these "flying" objects. Probably I misinterpret the object coordinate somehow.

Sorry, the maps are rendered in 3D so that you can fly around. I can of course make top-down screenshots of the maps. Thanks for your feedback.

Author here. The Ross’s Game Dungeon video was, to some degree, a motivation for me to start the reverse-engineering process, just for fun. The analysis took place over many years, and I figured out 95% of the format myself. AI helped me then with the coloring, which is pretty complex. I have read the Accursed Farms forum, of course. But it didn't help much.

The map mentioned there can be found as “Unknown Map” in the dropdown. However, I haven’t yet connected that map to the menu screen. It might be called “Tom’s Test Track,” because that string appears in the disassembly.

Integration into noclip might be easy, because I also have the geometry as a standalone .obj file.


I wish I had known this two years ago. I ended up writing my own embedded connection struct to trace these things [0].

  type Connection struct {
    net.Conn
    OnEventCallback func(clientClosed bool, serverClosed bool, err error)
  }

[0] https://github.com/s-macke/SlapperX/blob/master/src/tracing/...

That get's the job done too for those events depending on what you need them for. httptrace could be heavy handed if all you want is simple events like you show.

On weekends, yes. During the week, that’s also true if they arrive within a short time frame, e.g., three minutes. Almost no one looks at “New”. That is the real issue.

Author here. Yes, it is integral. I chose this approach to first show how to draw it from back to front, because the code is easier to understand this way.

I think it's worth noting that you can tilt with this method, but not roll.

Great for a helicopter game, Less so for general flight sim.

That was a large part of how games were designed back in the day. Start with what you have the ability to do, find the game that matches what you can do.


Notice the demo video from Comanche also shows roll.

Edit: To support roll, the renderer essentially rendered the voxel terrain into a frame buffer and then applied camera transformations that gave the appearance of a fully rotating viewpoint. The terrain itself was not being raycast through a true 3D voxel volume.


Nice to see an MCP integration here as well. In my experience, coding agents are great at analyzing MOS6502 code. Because the code is limited to only 64 kB, it does not overwhelm the agent. And in parallel it can write specs and even extract assets via normal coding tools.

Using my similar tool [0], I feel I get roughly a 100x speedup. I will definitely try regenerator2000.

[0] https://github.com/s-macke/OpcodeOracle


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: