I’m only making business card sized games now

Over the years I’ve worked on many games, some big, some small. I’ve found that the smaller the game, the more fun I seem to have making it. So I set out to make the smallest game I possibly could, and it was a blast.

Ladies and gentlemen, I give you the smallest game I’ve ever released. I call it “Tiny Ski!”, and it’s 960 bytes of pure magic. Please watch this short demonstration and continue reading for more info and source code.

Tiny Games, Big Ideas

We all know that modern games have become bloated, weighed down by useless features, achievements, anti piracy measures, piles of assets, and other junk. Not only that but developers are constantly taken advantage of, made to crunch for no pay, mass layoffs, etc. Lives have been ruined, and for what? So you could watch your horse poop or play dominoes in an open world game?

To quote the great Ian Malcolm, “They were so preoccupied with whether or not they could, they didn’t stop to think if they should.”

Actual Tiny Ski code printed on a business card.

There has to be another way. That’s why I say, instead of thinking big, we need to think small. So today, I am proposing a bold new direction. Imagine games so small that you can literally fit one in the palm of your hand.

Ladies and gentlemen I give you: Business Card Games. (Also, does my hand look weird?)

I’m not the first to create something that touched on this concept. You may have also heard about Andrew Kensler’s “Business Card Ray Tracer” Though his work isn’t a game, maybe we can use it as a size guideline for the format: 40 characters wide by 35 characters tall, or 1400 bytes.

There is of course the JS1K competition, which is has similar restraints but using JavaScript. People have created many amazing works, some of them games. However I don’t believe most of them work as well in this format. First of all the contest provides a shim which sets up the environment and many entries use unicode characters which would not work well in a printable format. That by itself might be ok, but many entries are compressed using a tool called RegPack, which works almost like zipping a JavaScript file. Nikhil wrote a nice explanation of how it works. It’s amazing tech but it has the side effect of making the code completely unreadable. I did submit a JavaScript version of Tiny Ski to the contest though, you can play the 1k version of Tiny Ski in your browser.

I did some research to find more past works that fit the bill, but there are surprising few. Of course many smaller games exist in binary format. Like BootChess for example, a chess game that is only 487 bytes. Of course there are many older roms like Atari 2600 games that are less than 2k. Also there are some really cool 1k intros. However that’s not really what we are looking for here. Only the source code size matters and the final binary will likely end up being much larger.

“An ofbuscated tertis” by John Tromp and Freek Wiedijk is nearly small enough as are some other IOCCC winners, but usually they are larger then ideal. However they do explore what I believe to be another key component: the code itself should look interesting. Unlike most other games, players are intended to view the actual code. And because the code is so highly compressed into a confusing blob, it’s better to focus on aesthetics over a futile attempt to improve readability.

For my first entry into the genera I chose a style of game that I am very familiar with. I’ve programmed variants of ski on many different platforms, starting with the TI-82 when I was in highschool. Last year even released an html5 version called Super Aspen. For this version, I boiled down the concept down to its essence, hopeful leaving something that is still fun and visually appealing. I even sacrificed some space to make it compile without warnings and work in older versions of visual studio using just a few standard include files.

So, without further ado, weighing in at 960 bytes, I present my first entry into the business card game format, “Tiny Ski”!

Tiny Ski Code

#include<windows.h> //  -+TINY SKI+-
#include<iostream>// By Frank Force
#include<ctime>     //  ski.3d2k.com
#define S SetConsoleCursorPosition
#define K GetStdHandle(-11)// IOCCC.
#define I U.dwCursorPosition// 2O19.
#define GO S(K,I)//..O           O..
#define D E(K,&U);//..O    \^\    O.
#define A std::cout<<//O           O
#define N(o)!(rand()%(o))//       O.
#define G(o)(1&GetKeyState(o)>>16)
#define E GetConsoleScreenBufferInfo
#define R COORD i={o-1,I.Y-11};S(K,i
void O(int _){while(_--)A(N(9)?'*':
'.');}int main(){_:short s=72,k=1,i= 
70,w=11,h=0,o=36,a[11][2],*g=*a,m,e= 
-1;while(w--)A'\n';srand(int(time(0) 
));while(++w<12||1[g]>=o&&*g<o){O(k)
;A'O';for(m=i;m--;)A(w%100?' ':'-');
CONSOLE_SCREEN_BUFFER_INFO U;A'O';O(
s-k-i);if(w%10==0)A' '<<w/10;D{R);}A
". .";GO;A'\n';o+=m=G(39)-G(37);D{R)
;}A(m?m<0?"/^/":"\\^\\":"|^|");*g++=
k;*g=i+k;GO;h=k<1?1:s<=k+i?-1:N(50)?
N(2)*2-1:h;k+=N(2)*h;Sleep(w<99?50-w
/3:16);N(5)?e=i<-25*e*N(i-15)||25<i*
e&&N(35-i)?-e:e,k-=e*(N(2)*k||s<k+i+
e),i+=e:1;g=a[w%11];}A"\n"<<w*.1-1.1
<<" meters!";while(!G(13));goto _;}

Features

  • Real time skiing simulation with state of the art ASCII graphics.
  • Fast and challenging arcade action gameplay.
  • Realistic player movement animation with snow deformation.
  • Procedural track generation that’s different every time you play!
  • Accurate metric system measurement with distance markers.

How to Build

  • Load up any version of Microsoft Visual Studio.
  • Create an empty project.
  • Add a new C++ file and paste in the code.
  • Build and run the project, or just press F5 to play in debug mode.
  • Once built the exe can be run on any windows machine.

Download

For those that don’t have access to Visual Studio (or are just lazy), don’t fret! I went to the trouble of building the game for you at no extra charge.

Controls

  • Left/Right – Move
  • Enter – Continue after dying
  • Pause – Pause the game
  • Maximize Button – Expand window for larger view of trail
  • Close Button – Exit game

Business Card FPS

In an unprecedented move I am also releasing a second example, what may be the worlds smallest FPS in C++. However, this time you’ll have to build it yourself. The full source code below includes a 3D raycasting engine, WASD movement, collision, procedural map generation, some fish, texturing, and distance shading. You can even resize the console window and shrink the font to get a high res image! Also check out OneLoneCoder who has an excellent video explaining how to write a basic raycasting engine (though my code works differently).

Business Card FPS Code

#include <windows.h>//BUSINESS CARD FPS
#include <cmath>    // By Frank Force
#define A return    // 2019 ><{{{*>
typedef double O;typedef int e;struct f
{f(O h,O y){a=h;o=y;}f(O g){a=sin(g);o=
cos(g);}f operator+(f h){A f(a+h.a,o+h.
o);}O a,o;f operator*(O h){A f(h*a,h*o)
;}};O b(e y){A O(1&GetKeyState(y)>>16);
}const e i=1<<19,s=97;e h[i]={0};e l(f
r){A h[e(r.o)*s+e(r.a)];}e main(){e a,L
;O u=7;for(L=9215;--L>s;)h[L+(rand()&1?
1:s)]=(2+L)%s>2;h[s+2]=1;f h(2,1);char
F[i],N[]="#+. \xDB\xB2\xB1\xB0";void*_=
CreateConsoleScreenBuffer(3<<30,0,0,1,0
);SetConsoleActiveScreenBuffer(_);COORD
H={0};CONSOLE_SCREEN_BUFFER_INFO T;_:G\
etConsoleScreenBufferInfo(_,&T);DWORD Y
;Sleep(16);f o=f(u+=(b(68)-b(65))/30)*(
b(87)-b(83))*.1;h=h+f(o.a*l(h+f(o.a,0))
,o.o*l(h+f(0,o.o)));e I=T.dwSize.X,S=T.
dwSize.Y;for(L=I;L--;){f n(u+atan2(L/O(
I)-.5,1)),Y(e(h.a),e(h.o));O s=n.a>0?1:
-1,H=n.o>0?1:-1,E=abs(1/n.a),u=0,o=abs(
1/n.o),y=E*s*(Y.a-h.a+(s>0)),W=H*o*((H>
0)+Y.o-h.o);f i(s,H);while(!u){y<W?y+=E
,u=1,Y.a+=i.a:(W+=o,Y.o+=i.o,u=2);u*=!l
(Y);}O d=u<2?(Y.a-h.a-i.a/2+.5)/n.a:(Y.
o-h.o-i.o/2+.5)/n.o,T=S/2-S/(d+.1),p=(u
<2?n.o*d+h.o:h.a+d*n.a)+.1;for(a=S;a--;
)F[a*I+L]=e(a>S-T?7-8*a/S:T>a?8*a/S:d>9
?7:(.2>p-e(p))+d/3+4)[N];}WriteConsole\
OutputCharacter(_,F,I*S,H,&Y);goto _;}

The Future is Tiny

This is only the beginning of our exploration into this new format. There is plenty of room for innovation. I look forward to seeing what you all can come up with! If you made or know of any games with source code that can fit on a business card, please post them below. I’m thinking about setting up a Business Card Game Jam on itch.io later this year, does that sound fun? Let me know, thanks for reading!

This entry was posted in Game Dev and tagged . Bookmark the permalink.

31 Responses to I’m only making business card sized games now

  1. Pingback: New top story on Hacker News: I’m only making business card sized games now – Hckr News

  2. Pingback: New top story on Hacker News: I’m only making business card sized games now – Golden News

  3. Pingback: New top story on Hacker News: I’m only making business card sized games now – Outside The Know

  4. Pingback: I’m only making business card sized games now | My Tech Blog

  5. Pingback: New top story on Hacker News: I’m only making business card sized games now – News about world

  6. Pingback: I’m only making business card sized games now – INDIA NEWS

  7. Pingback: New top story on Hacker News: I’m only making business card sized games now – Latest news

  8. Pingback: New top story on Hacker News: I’m only making business card sized games now – World Best News

  9. TT-392 says:

    Ok, so most new programming technologies allow for bloatyer and shittier code because there is just more computing power. So how about someone designs some sort of protocol like nfc or qr that can only fit a credit card sized piece of code so that people are forced to think small again.

    • Frank says:

      I think it just has to be more about self restraint and willingness to cut unnecessary features early on. There are already plenty of games out there doing this well.

      Making games as small as Tiny Ski is a bit extreme, though it was super fun to work on, I wouldn’t want all games to be like that!

  10. Pingback: I’m only making business card sized games now – Hacker News Robot

  11. camochameleon says:

    I’m sorry but you missed a huge trick here not calling it ASKII.

  12. Pingback: early games – Michael Kimsal blog

  13. John Tromp says:

    You managed to mis-spell not only my first and last name,
    but also the name of the game :-)
    Also worth mentioning is my obfuscation co-author Freek Wiedijk.

  14. Applewine McWeid says:

    Somehow the Code for the tiny FPS does not work for me. I get 4 errors in visual studio.

  15. Phariax says:

    What about piroot? Have you stopped that?

    • Frank says:

      I’m working on converting it to be business card sized. ;)

      Actually, I am still working on it, and a lot of other stuff too! Right now I’m in the middle of prototyping a new experimental game idea that may take a few weeks.

  16. Phariax says:

    “I’m working on converting it to be business card sized. ;)” :D :D

    The new proto sounds interesting, keep up the good work. I was playing around with your engine, and I like it, (however I am just a wannabe coder), and I seen some of your Ludum Dare stuff, and there are very cool game ideas.

  17. Pingback: I made 7 demos in 2 weeks for JS1k! | Killed By A Pixel

  18. Pingback: 2019 – Year In Review – Adventures in Tiny Coding | Killed By A Pixel

  19. Pingback: Adventures in Tiny Coding – My 2019 In Review | Killed By A Pixel

  20. zikey says:

    Thought I would share my own thoughts on the subject…

    I think the actual required size for games follows an exponential curve. Meaning that you start off barely able to do anything – 446 bytes for basic tetris, 487 bytes for extremely simplified chess. But complexity is rapidly achieved with more data. 1022 bytes gets us a working Space Invaders clone. Once we reach 4096, we have countless endless runners, and some super clever games like Conga 4096 for the C64. Once we reach 16,384, we get some actually interesting 8-bit platforms with substance. The JS13k also shows amazing things possible with just 13kb.

    Most of the what takes up a game’s size is non-algorithmic data, usually high quality sound/music, high resolution textures, high poly 3d models, animations, text, etc. And to an extent this size can be reduced with compression.

    Also, game engine size should be exempt (or at least considered separately). A lot of consoles or computers had dedicated hardware for sound generation (FM synthesis, SID chip etc, echo, reverb etc.) or graphical effects (screen modes, color math etc), which games used directly, which often need to be recreated in an engine. Ideally, the game engine should be treated as the platform itself (equivalent to a C64 or SNES), and the size of the game logic/data is separate from the engine.

    Lets say you have a highly flexible and optimized game engine library – lets say 200-400KB compressed (depending on 2D/3D requirements on the linker). You can probably get pretty far by measuring the game assets separately from it.

    In my opinion, there are 4 ‘tiers’ of small-sized games (only considering the game code and asset size):

    1. 16KiB (16,384 bytes) to 32KiB (32,768 bytes)

    16K is the smallest size that can be considered ‘fair’, for a complete, 0.5-4 hour game. Requires heavy procedural elements and lots of clever data optimization and compression. Music variety has to take a backseat (even synthesized music needs at least 2K per full length song that isn’t just a loop). 32K being the maximum of this tier, allows a bit more flexibility.

    2. 128KiB (131,072 bytes) to 512KiB (524,288 bytes)

    First, a note about 64K, which might think is a natural next choice. The 96K game competition shows that 64K is just not enough to make serious games, but at the same time it’s too lenient to make highly constrained games. 16K is a popular category for C64 and MSX homebrew and plenty of great games have been made in that category. NES homebrew games are often 40K which is basically 32K when you consider the separation of CHR/PRG ROM.

    I consider 128K to be the smallest size that can be considered for constrained ‘serious’ games. This is the category that ‘.kkrieger’ is in (highly compressed 3D FPS). 128K should be enough to do low-poly 3D games with heavy utilization of procedural elements. This category can scale up to 512K.

    3. 1MiB to 4MiB

    This is the ideal size for your modern indie retro game trying to copy the SNES era. Cave Story could easily fit in this category if it was a bit more optimized. And plenty of modern retrogames could be made to fit in this category with excellent size optimizations and skilled programming. Obviously low-poly 3D games could easily fit in this category as well.

    4. 16MiB to 64MiB

    This final tier is is specifically for large-scale games, fitting for immersive 3D games. Real world examples are: Ocarina of Time (N64) at 32MB and Vagrant Story (PSX) at ~93MB, and those could easily be compressed further. This category has tons of potential for full scale games using Dreamcast/PS2-level graphical complexity. It is a category that still requires clever optimizations and compression, but with modern shaders, codecs etc., great results should be possible.

    ——–

    Any higher than that and it’s no longer a sizecoding challenge. Plenty of indie Unity games (usually 2D) end up 150-200 MB without even trying. End users often consider 500-1000MB ‘small’ games.

Leave a Reply to Frank Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.