| ▲ | This game is a single 13 KiB file that runs on Windows, Linux and in the Browser(iczelia.net) |
| 153 points by snoofydude 9 hours ago | 46 comments |
| |
|
| ▲ | TuringNYC 7 hours ago | parent | next [-] |
| On a related note -- when I see the minuscule filesize of the original Zelda game on emulators, I marvel at how little text/code/information could produce how much wonder, how far-reaching impact, and how many hours of enchantment for me. https://en.wikipedia.org/wiki/The_Legend_of_Zelda_(video_gam... |
| |
| ▲ | erwincoumans 30 minutes ago | parent | next [-] | | Indeed, magic. How about the Commodore 64, there was a game (Eindeloos, Radarsoft, 1985) within 64kb that has a huge map. Someone recently (after 40 years!) extracted the map (500 screens) and the png alone is 800kb. See the story an zoom in and try finding the little heart in the map!
https://adayinthelifeof.nl/2025/03/07/endless.html | |
| ▲ | 3RTB297 an hour ago | parent | prev | next [-] | | My favorite slight of hand was that all the dungeons and caves were part of a single rectangular map. Designers carved out a few specific designs, then other levels were clearly what worked with the remaining map screens available so it all fit in the space they had, with caves thrown in to take up single screen gaps. https://ian-albert.com/games/legend_of_zelda_maps/ | | | |
| ▲ | jsheard 6 hours ago | parent | prev [-] | | Zelda 1 was 128 kB, for those wondering, and that's without any compression. Double that for the sequel. | | |
| ▲ | rlv-dan 29 minutes ago | parent | next [-] | | > without any compression Perhaps not compression as we see it today. But one could argue that tile based graphics and code based music is a form of compression. Old games used a myriad of cool tricks to get around their limitations. | |
| ▲ | Andrex 5 hours ago | parent | prev [-] | | That honestly doesn't seem too bad. Zelda 1 is relatively large but it reuses a lot of assets and honestly probably doesn't have that much text. (More than a Mario but way less than a Dragon Warrior.) |
|
|
|
| ▲ | nine_k 9 minutes ago | parent | prev | next [-] |
| What entertains me most is that the thing contains three independent implementations of a graphics-based game, strung together, wrapped into a crafty multiplatform loader... and it all still takes 13 kiB. |
|
| ▲ | zamadatix 9 hours ago | parent | prev | next [-] |
| For me: - Browser: works after renaming to .html - Linux: "./snake.com: line 20: lzma: command not found". Installing the xz package makes it work (already had XWayland enabled so X11 worked, but may be needed if you have a strict Wayland session). - Windows: As either .com or renaming to .exe I get "The application was unable to start correctly (0xc0000005). Click OK to close the application." Not sure how to make this one work, it's definitely not AV related though (I have that stripped in this sandbox VM). Edit: Got it working in all 3 now. On Windows I still had DEP enabled on all programs to test some apps earlier, turning that back off allowed it to launch. |
| |
| ▲ | w4yai 8 hours ago | parent | next [-] | | Works for me on Windows 11 | | |
| ▲ | zamadatix 8 hours ago | parent [-] | | Hmm, Windows 11 25H2 here as well. Redbean works so there must be something about this particular approach combined with some unknown setting on my install. Edit: Got it working, was DEP. | | |
| |
| ▲ | deklesen 8 hours ago | parent | prev | next [-] | | its written in the post | | |
| ▲ | zamadatix 8 hours ago | parent [-] | | If you mean lzma it wasn't immediately apparent to me it was a binary requirement, but inspecting the hex dump at the end + the message is how I figured out it was. I wonder how much space you lose dropping lzma and doing some other method as "tail -c+4294 $0|head -c 5061|lzma -dc>/tmp/a;chmod +x /tmp/a;(/tmp/a&rm /tmp/a);exit" would be more universal and the linux portion isn't all that big. If you mean the .html rename or whatever my Windows problem was, I must be missing it. Edit: Windows was DEP. |
| |
| ▲ | GlumWoodpecker 8 hours ago | parent | prev [-] | | If I ran it with just $ chmod +x snake.com
$ ./snake.com
... then it would try to use Mono to launch it: Cannot open assembly './snake.com': File does not contain a valid CIL image.
But, running it explicitly with Bash works: $ bash snake.com
Pretty nifty but doesn't work out of the box on any Linux, at least :p Running Debian 13. | | |
| ▲ | seba_dos1 8 hours ago | parent [-] | | > ... then it would try to use Mono to launch it: That's because of the binfmt handler that Mono installs which matches the PE header. |
|
|
|
| ▲ | chii 19 minutes ago | parent | prev | next [-] |
| i wonder if such a mechanism could be "enhanced" to produce a true "universal" binary, using a source-to-source compiled language like Haxe? With Haxe, you can write the application once, target both win32 and linux by compiling to C++ (which then you compile using the platform specific tooling for each paltform), and then target html by compiling to javascript. Then use the same concatenation mechanism and header abuse as described in the article to have all three targets merged into one file that can then be run on all platforms! |
|
| ▲ | nvllsvm 8 hours ago | parent | prev | next [-] |
| Not cross-platform, but I'm reminded of the kkrieger game for Windows which was a 96k FPS game that looked visually impressive for the time. https://web.archive.org/web/20100304155706/http://www.thepro... |
| |
|
| ▲ | wasmperson 5 hours ago | parent | prev | next [-] |
| I extracted the linux executable and was surprised to find that both readelf and objdump choke on it despite it loading and running correctly. Some investigation reveals that the name of the dynamic linker was shoved into the "unused" fields in the PT_DYNAMIC header entry to save space: Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
INTERP 0x0000000000000088 0x0000000000010088 0x0000000000010088
0x000000000000001c 0x000000000000001c 0x0
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
DYNAMIC 0x00000000000000e0 0x00000000000100e0 0x6c2f343662696c2f <-- "/lib64/ld-linux-x86-64.so.2"
0x2d78756e696c2d64 0x732e34362d363878 0x322e6f
readelf: Error: the dynamic segment offset + size exceeds the size of the file
LOAD 0x0000000000000000 0x0000000000010000 0x0000000000000000
0x0000000000001dc0 0x0000000000005660 RWE 0x1000
Two questions:1. Was this done manually or is there a tool you're using which does this? I see other size-reduction tricks in here as well. 2. Does anybody know of a tool for examining executables which doesn't crap out on binaries like this? |
| |
|
| ▲ | madduci 35 minutes ago | parent | prev | next [-] |
| The binary relies on the runtime, so yes it is nice. Forma instance, a static compiled and linked "hello world" in C on Linux is around ~785KB |
| |
| ▲ | oguz-ismail2 20 minutes ago | parent [-] | | > a static compiled and linked "hello world" in C on Linux is around ~785KB Huh? $ musl-gcc -xc -static -Wl,-z,norelro -Wl,-z,nosectionheader -Wl,-z,noseparate-code -s - <<eof
#include <stdio.h>
int
main(void) {
static const char s[] = "Hello, World!\n";
fwrite(s, (sizeof s)-1, 1, stdout);
}
eof
$ ./a.out
Hello, World!
$ ls -l a.out
-rwxr-xr-x 1 oguz oguz 4976 Jan 12 09:38 a.out
And if that's not enough $ musl-gcc -xc -static -nostdlib -fcf-protection=none -fno-asynchronous-unwind-tables -fomit-frame-pointer -Wl,-z,norelro -Wl,-z,nosectionheader -Wl,-z,noseparate-code -s - -lc <<eof
#include <unistd.h>
void
_start(void) {
static const char s[] = "Hello, World!\n";
write(1, s, (sizeof s)-1);
_exit(0);
}
eof
$ ./a.out
Hello, World!
$ ls -l a.out
-rwxr-xr-x 1 oguz oguz 487 Jan 12 09:58 a.out
|
|
|
| ▲ | trollbridge 8 hours ago | parent | prev | next [-] |
| One of the interesting things about Polyglot is that nobody did it any sooner. It would have been feasible a decade ago or two ago. |
| |
| ▲ | Retr0id 7 hours ago | parent [-] | | Now I wonder when the first polyglot file was published. I kinda just assumed they'd been around forever. EICAR.COM comes to mind as a COM/plaintext polyglot |
|
|
| ▲ | socketcluster 7 hours ago | parent | prev | next [-] |
| I love the idea of applications which exist in one file which you can run anywhere. I've been working towards this with my serverless platform; you can build complex data-driven apps with just one .html file and mostly declarative HTML markup (thanks to web-components which are loaded from a remote server). With modern browser features, you don't need a bundling system. Once you do away with it; a whole universe is opened up. The ability to load .html files over the file:// protocol is a powerful, often neglected feature. In practice, it means you can double-click an HTML file and it runs an app in your browser instantly. |
| |
| ▲ | billfruit 2 hours ago | parent | next [-] | | How are you approaching the development of your single file html apps, is there any examples publicly available, sounds very interesting. | |
| ▲ | Retr0id 6 hours ago | parent | prev [-] | | Sadly a lot of browser features are inaccessible from non-https contexts. | | |
|
|
| ▲ | ValdikSS 7 hours ago | parent | prev | next [-] |
| https://js13kgames.com/ |
|
| ▲ | netsharc 6 hours ago | parent | prev | next [-] |
| Semi-related: Windows EXE files are runnable in DOS (at least when DOS was a thing, so for Windows 3.1x or 9x), but most of the time the DOS part just prints "This program requires Microsoft Windows." and exits. An exception is regedit.exe, that one can use to import registry values even in DOS. (Huh, although, how does it do that without using Windows API?) |
| |
| ▲ | chii 2 hours ago | parent | next [-] | | > Huh, although, how does it do that without using Windows API? without knowing anything, i am going to guess that they could either directly import the same code that the windows api uses (either via knowing where the implementation code resides and load that), or even statically link the library! After all, regedit doesn't need to obey cleanliness rules that other non-first-party programs would need to - presumably, because if those registry editing api/format changes, regedit would get updated along with it! | |
| ▲ | b1temy 5 hours ago | parent | prev [-] | | > An exception is regedit.exe This might have changed at some point. I was curious about the latter part of your question on how it made changes without the Windows API (I assumed it used an older DOS API), but my `regedit.exe` _does_ have the `This program cannot be run in DOS mode.` DOS stub in it. |
|
|
| ▲ | hyperbrainer 4 hours ago | parent | prev | next [-] |
| Reminds me of the Cosmopolitan project: https://github.com/jart/cosmopolitan |
| |
|
| ▲ | beeflet 3 hours ago | parent | prev | next [-] |
| You don't need to rename it to an html file, just serve it with with the following header: Content-Type: text/html |
|
| ▲ | indigodaddy 8 hours ago | parent | prev | next [-] |
| Wonder why they don't give a demo/link to the browser version |
| |
| ▲ | nxrabl 7 hours ago | parent [-] | | It's the same file, you just rename it to end in '.html' | | |
| ▲ | indigodaddy 6 hours ago | parent [-] | | sure but they have a blog and a webserver that's serving html. just put the .html version there so i dont have to download anything or mess about too much. just want to click and see it |
|
|
|
| ▲ | bananaboy 8 hours ago | parent | prev | next [-] |
| Very clever! |
|
| ▲ | gaigalas 7 hours ago | parent | prev [-] |
| Quite cool. You could distribute it as `.html` only, and use JS to offer a local download link to itself in the correct extension. A polyglot installer, of sorts. For example, this gist is an HTML that, when opened, offers a download zip of its DOM in whatever state it currently is: https://gist.github.com/alganet/c904acb57282402fc0bd724f1eeb... I think you can use something similar to get the entire page contents as a blob, but I never tested with binary data in actual browsers. Perhaps even patch it to avoid the initial windows error. |