Why did I set my sights on the Atari 2600 for a discussion of pixel art? The main reason is that the machine gets a lot flack unjustly, I'm sure you've heard derogatory statements like "That looks so bad it looks like Atari." or patronizing it "It doesn't look good but what can you expect, its Atari.". Every game system has its strengths and weaknesses but each has a maximum quality level that should always be met, like with pixel art you want it to look as good as it possibly can get whether 2600 or PS3 the standard should always be the same.
I'd say its safe to say we're a visual lot on this pixel art forum and although being a good artist doesn't negate programming ability its safe to assume an abridged cliff notes approach is more useful here than a long description of how the TIA works. I'm not a great writer so might as well try some descriptions out and work out the kinks.
Well might as well start by saying that 2600 graphics design is directly transferable to the Atari 5200 and 7800 as the hardware architecture of graphics rendering is pretty much the same. So even if you go overboard on a design and it ends up not being possible on the 2600 you can always go up a hardware generation. I mostly focused on the 2600 because it was the most popular of the 3 consoles having the longest life span ever for a game console.
I don't know the 7800 well enough but the 5200 has twice the sprite objects of the 2600 and includes hardware acceleration for many of the common code kernels used in Atari based graphics rendering so its significantly faster and more versatile despite not selling very well when it was released. One good thing is that Atari 400/800 computer line(Which did sell fairly well.) and the 5200 console share the same hardware design except for a few small differences but it does expand the retro user base further for software of this type.
Atari 2600 object list: Playfield, Background, Ball, Player0, Missile0, Player1, Missile1
Atari 5200 object list: Playfield, Background, Player0, Missile0, Player1, Missile1, Player2, Missile2, Player3, Missile3
*As you see 4 Players & Missiles but I couldn't find a Ball object on the 5200, Atari cutting to the bone as always offering no extras.
I should explain Color Clocks since the 2600 doesn't technically deal in pixels with the TV acting as part of the video card. Despite looking like pixels they are actually analog drawing units thus being able to literally stretch instead of doing so with scaling calculations like you would normally do with pixels. Anyway I'm making it sound complicated so here's a conversion table so you can use actual 2600 terminology so mis-communications don't occur if you pursuit a 2600 homebrew project and need to speak more literal Atari terms.
1 color clock=2 pixels wide
2 color clocks=4 pixels wide
4 color clocks=8 pixels wide(A Playfield pixel is 4 color clocks wide.)
8 color clocks=16 pixels wide
...and so on.
I find this table helpful when trying to describe the dimensional size of a sprite or explaining distances to an actual 2600 programmer. Not to knock programmers but they tend to be a literal bunch without any means of interpretation for less than specific programming terms. Perhaps I'm being hard on them since "moving" within any programming environment is probably hard that sticking to a single mind set makes navigation easier.
Let's explain the canvas size I use when screwing around with 2600 graphics design. It's 320X192, while the 2600 is technically capable of doing more than 192 vertical lines of resolution, on average most games do not exceed this amount for CPU and overscan considerations. Despite using a single layer canvas the actual 2600 is a multi-layer system of differing resolutions.
My buddy SeaGTGruff uses 800X576 as he is trying to approximate the vertically stretched pixel into a crisp exact pixel unit of 5:3 in shape but even that isn't perfectly 4:3 in aspect ratio. In the end the stretch is "soft" and analog that I think for the sake of file sizes in mockups 320X192 would suffice as old VGA 320X200 was also a stretched standard too.
*Exceeding 192-200 active scanlines can result in the top & bottom of the screen being chopped off. While it varies from TV set to TV set 192 is the safe overscan limit most likely to work with the widest range of NTSC sets. The overscan is different for PAL standard but you would be better off asking someone who lived in PAL regions to get a proper assessment since I just barely understand NTSC as a standard.
The Playfield is your primary means of rendering level graphics which is only 40 "pixels" wide. Its not as bad as it seems since realistically much of level construction is bulk fill but you do have the option of changing the color per scan line, changing the color mid-line, or stripping out pixels and having the background color show through the holes. Before someone mentions mirrored Playfields, asymmetry has been conquered on the 2600 so its "mostly safe" to draw freely across the screen with Playfield pixels.
Overall the Playfield should be thought as a single image or a low resolution bitmap that fills the screen in regards to the degree of segmentation possible. There is no tile sheet or tilemapping to speak of except for a few small exceptions(The Playfield columns,the Missiles, and the Player objects.). While you can design blocks of graphics to specific block sizes for the sake of balancing the level graphics scale to the sprite scale for the most part the Playfield is just one big chunky bitmap, sort of liberating in its own way.
Here's some testing of block sizes from 1X1 up to 8X8 blocks(1X6 pixel block).
Something of note about the Playfield is its a 20 bit or pixel register split into 3 columns of 4 blocks wide(PF0), 8 blocks wide (PF1), and another 8 blocks wide (PF2) to the center which by default mirrors or tiles the other half to complete the full 40 of the screens width(4-8-8-Center-8-8-4). I mention this since these horizontal breaks can be used in a semi tile fashion to repeat image blocks or to omit areas of the screen as in pillar boxing. Yeah I know they are giant tiles but it is supported in hardware.
For the curious I'll mention vertical splitting of the Playfield for tiling purposes, while a single split added for the HUD is common to 2600 games splitting the Playfield vertically for tiling purposes is a difficult programming task only accomplished by a few 2600 masters over at AtariAge (EG. Boulderdash on 2600,check it out.).http://www.youtube.com/watch?v=w6Ge6G9sT9E
The complication in smaller scale tiles is the code kernel related to the division itself as the Playfield image data (tiles) can exist in a variety of sizes or dimensions when not being displayed but when actually rendered on screen the 40 bit wide Playfield register is the end result always meaning it has to be converted to the larger Playfield bank size (4 & 8 bits wide respectively.). It really comes down to overburdening the CPU with so many tasks and those precious few cycles afforded to you.
-Standard Display Kernel(Default use of all sprite objects.)
-Tile sheet combiner
-Standard Display Kernel
-Tile sheet combiner
-Missile Sprite Left Kernel, Missle Sprite Right Kernel
-Ball Sprite Player Extension Left Kernel, Ball Sprite Player Extension Right Kernel
-Standard Display Kernel
Although just a basic example you can see how tasks accumulate and the timing and execution of them can overwhelm the 6502 CPU quite easily when the vast majority of CPU time is spent with real time rendering everything both visible and behind the scenes with no hardware assistance.
This aspect wouldn't be so bad if there was more room to segment and module the engine like we do now for convenience at what is now a minor cost in CPU time. However with the 2600 there is little opportunity to segment making the engine a fully integrated optimized code base, much like the game Jenga push one block out and the whole structure could cease to work.
As an example David Crane didn't have a Lives meter in Pitfall initially until his colleagues badgered him to add it which was worth while since it made the game more accessible to the large majority of players. Despite this addition being warranted he basically had to take the entire engine completely apart to add this gauge since it was so tight with 1-line kernel graphics and the level generating demands.
I bring this up since the 2600 development environment is the polar opposite of something like Flash where you can just add things at will. I'm a terrible game designer with bad habits but even I would say a well thought out design document is needed before you actually make an Atari 2600 game.
Sorry this should have been in here from day one.
The Playfield has a SCORE bit which allows you to change the Playfield color at the center of the screen to a different color for the left and right side of the screen. This is hardware based so it doesn't come with the usual software based CPU costs of mid-line color changes. So this is another safe bit of color change you can invoke in the Playfield.
Here's an example of the Playfield columns, added some arrows to show the default mirroring directions.
Same thing but here's the Playfield tiling option which in my opinion doesn't get employed enough despite being a default setting.
Something I should mention about using the Playfield columns as a tile grid is that you can only use it to expand configuring options under an asymmetrical rendering setup but not to save image space because the Playfield register has a fixed linear reading order. To be specific you actually use 50% more image space IE. 2 full Playfields for asymmetrical rendering since each Playfield Tile has to include both a left and right facing copy in order to render in the correct orientation for each side of the screen.
The Mirrored or Tiled Playfield modes are completely fixed layouts where you can omit a column completely but any exchange of one column graphic for another would be reflected in its opposing column register.
Lastly these are 2 column widths of 4 and 8 bits respectively which aren't interchangeable so its an either or situation in that regard making 2 distinct groups or types of Playfield columns.
Whoops sorry again.
The Background layer actually does have a small amount of resolution control in it that you can change the color per scanline IE. a 1X192 image layer. Despite limitations these 2 layers combined (Playfield & Background) do offer possibilities of 2 color background graphics if catered to.
Here's an example of a simple background made using the Background layer, I could use the Playfield to layer on some other details, or make a giant Playfield sprite, etc.
2 Color tiles:Mostly concept work of Playfield+Background colors and others that use Missile layers.
Despite a lack of true tiling options its best to cater to the Playfield as if it had tiling when it applies to bitmap patterns and you should also try to fit things to the natural horizontal breaks in the Playfield register of 4 or 8 bit wide banks.
Options: Default savings through mirroring always present with tile mode offers varying amounts of image space savings.
-40:40 bits(Playfield pixels) wide or the full screen of completely freeform bitmap data, other than mirroring no image space savings.
-40:12 bit wide tiles, partial savings in PF0 & PF1 which do tile but PF2 requires 2 unique tiles or island tile.
-40:8 bit wide tiles, decent tiling option as two-4bit and one 8:bit wide Playfield bank can tile fill whole screen.
-40:6 bit wide tiles, partial savings in PF0 & PF1 which do tile but PF2 requires 2 unique tiles or island tile.
-40:5 bit wide tiles, tiling option will save space but right side of screen irregular unless you use isolated tiles with border trim or islands.
-40:4 bit wide tiles, best tiling option as one-4bit and one-8bit wide (Two 4-bit wide tiles paired)Playfield bank can tile fill whole screen.
-40:2 bit wide tiles, same as 4 bit wide option.
The canvas is 320 wide simply because 40 Playfield pixels fit inside as do Player objects drawn to double wide res(160 to 320) or C64 width standards and Missile and Ball bits at variable widths. So in this canvas approximation all your sprite object designs will fit and align to the varied 2600 layer resolution scales.
I mentioned 192 as the basic height resolution used in most 2600 games but it is actually variable based on the thickness of line kernel used within the engine, using thicker lines is used to save cycles during rendering but typically helps with animation smoothness. At 192(1 line) regardless of pixel widths its about as sharp as C64 graphics, at 96(2 line) lines of vertical resolution its close to 1:1 pixels looking a lot like an Intellivision standard, at 64(3 line) its gets chunky and similar to a 80X64 screen resolution in practice, and 48 lines(4-Line) which is pretty much like 64 vertical lines but taller lol.
You can actually set line thickness differently between all 6 sprite objects per scanline (Playfield/Background/Ball/Player0/Missile0/Player1/Missile1) but for visual consistency and engine efficiency its best to stick to 1 global line thickness standard. If you do want to differ the height resolution its best to cordon it into deliberate areas of use like a single object or scanline height zone instead of changing it sporadically since everything invoked including line thickness changes consume those precious 76 machine cycles per scanline.
EGs. HUD bar scanline zone is 1-Line but game graphics region is 2-Line rendered, Player objects are 1-Line but all other objects are 2-Line rendered.
Playfield resolution options:
Note this example demonstrates line thickness but the pixel width is strictly different between Playfield, the 2 Player objects, and the 2 Missiles and the Ball which all have different pixel width standards(EG. 1 Playfield pixel is 8 pixels wide in the canvas while 1 Player object pixel is 2 pixels wide in the canvas.).
The grid scale in the canvas uses 40X32 blocks of 8X6 pixels each to compensate for the heavy vertical stretch that occurs when graphics are actually rendered to the 4:3 aspect ratio. Its not perfectly exact but its a close enough in dimensional size that each block will be close to equal in width and height when stretched. For game graphics I just rescale my mockups to 800X600 to test how tall things will be after stretching.
Overall the canvas block size of 8X6(Well really 1X6 on an actually 2600.) pixels is a sturdy guide for plotting out level structures and should be thought of as your minimum level block size akin to the 8X8 used on other platforms.
Here's an example of what 3 line kernel graphics would look like.
As you can see its very tight and the thicker vertical lines handicap any finer resolution horizontally in composition, used 4 pixel width standard to compensate. Level layouts are definitely made smaller or more simple at 3 lines thick out of necessity, it looks like 2 floors would probably reasonable and some added vertical scrolling or extremely spartan level design would balance out screen space constraints.
I know I overdid it a bit in colors and bits per scanline but it was mostly just seeing what could be drawn into the resolution well. Such a setup would have benefits in cycle cost reduction being only 64 lines tall, things like animation smoothness, multi-color graphics, and sprite multiplexing would have less drag on the CPU even when used in combination compared to doing the same with 1 or 2 line rendering.
Actually the formula for vertical aspect ratio stretch that SeaGTGruff gave me should work with one tweak. Take your height resolution value multiply that by 3 and divide that by 5 to get the color clock width, lastly multiply that by 2 to get the width resolution that is compatible with the canvas size I posted. Depending on the result of the width value you get you might have to round up or down so it will fit the resolution limits.
FYI I tried favoring the width dimension when trying for approximately equal height and width after stretching but was informed that catering to the height value was better since it falls more in line with how efficient kernels and graphics are rendered on the 2600 IE. per vertical scanline which is especially true with curves & circles.
Its not that you can't favor the width its just that it will be far less efficient in cycle usage if you vary line thickness and horizontally shift pixels differently per vertical zone in actual rendering just to get the exact height you're aiming for, its better to have a consistent basic display kernel using one line thickness option top to bottom and take advantage of tables and inverting width and position values for less CPU drag. It depends on the context which dimension you favor EG. Game graphics versus an Art Slide.
Sprites? Whoops wrong credit, here is where I found these animal sprites. http://www.photonstorm.com/archives/2291/16x16-pixel-art-tutorial
The 2 player objects are 8 bits or pixels wide but since they are double wide they take up 16 pixels of width of on screen width not unlike C64 sprites. You have unlimited height resolution but that is actually a pretty useless feature except for a few isolated contexts where that factor can be utilized. You can pair both Player objects together for a 16 pixel width but its quite a sacrifice unless you can ensure both players never reside on the same scan line as in a Tennis game where the net separates them or that all other sprites can be made using Missile0, Missile1, and or the Ball pixel.
The standard 2600 sprite description of 2 Player objects 8 pixels wide is often enough to stop a pixel artist dead in their tracks based on its meager offering so I'll instead go over some options to make the 2600 less stifling.
The 2 Player objects will probably be the most familiar and friendly object found on the 2600 as its the closest you'll get to standard pixeling. There are quite a few editing programs to create standard Player object sprites but I haven't found any that support bit constructed sprites or extensions to the Player object as that is typically handled by a programmer.
The easiest way to describe Missile0, Missile1, and the Ball is to think of each as a single pixel with multiple width settings and any height you choose. There names denote there most infamous uses in most 2600 games as each Player object has a Missile object that acts as its projectile and the Ball object or sprite was first used as a ball that the 2 players could bat around. Over the years after the 2600's release both Missiles and the Ball started to get used in a myriad of ways beyond there initial purpose.
You can actually extend the default Player objects 8 pixel width using the Player objects corresponding Missile object up to a minimum 9 pixels wide with a basic kernel. Pretty basic but when dealing with so few pixels even a single pixel is a banquet. I mention the minimum of adding a single pixel to the width of both Player objects with there corresponding Missile because the Missile can copy 3 times like the Player objects so you can make three 9 pixel wide Player sprite copies quite easily.
The next best step to extending Player width is to utilize Missile0, Missile1, and the Ball bit all along one scanline which can each be set to different widths greatly expanding what can be done using the Player sprite object. Something to note about this usage is that if you need a lot of projectiles you won't have free bits to use for pixel extensions (Melee VS Shooter).
The 2 Player sprite objects can be copied 3 times per scan line at 3 possible mandatory distances from each other, the minimum gap size is 4 blocks(32 pixels) wide with the Player object included within that gap distance specifically to the left most side of the gap(See my spacing chart below.). All Player copies move in unison by default while true independent movement of entities requires flicker based multiplexing of Player objects or 1 object rendering multiple sprites with multiple screen renders(EG.Pac-Man ghosts.). The next 2 wider gap distances simply double the previous width or 32,64, and 128 (EG.Space Invaders 2600). This mandatory gap distance also applies to both Missiles objects and its 3 copies. The Ball object has no copy ability at all so copy gap distance is not applicable
2 sprites, that's not very many and I need more?
The 2600 is extremely frugal in its construction since it doesn't have a frame buffer or video RAM of any kind meaning it has to refresh the screen pixels constantly without a break. While this puts quite a burden on the CPU as the level of instruction complexity is fairly high to form the graphics on screen it also mean everything is modular and alterable in real time as everything is real time rendered by default.
One interesting property of this is using one Player object sprite across multiple sprites since you can switch the bitmap pattern within set heights of vertical resolution as each objects copying ability and appearance is only influenced or limited by the scanline height zone it occupies. The height is completely negotiable as every sprite object has unlimited height resolution so you can set its vertical zone of influence to where ever you desire.
How far can you push the Player objects?
The most they have ever been pushed practically is 6 sprite blocks of unique appearance through multiplexing or flicker based passes. One of the more popular implementations of this is the Title Screen Kernel which can essentially render a bitmap of 48 pixels of width and any height you desire but only that since the timing and CPU needs are quite high that nothing can render on or beside it. As you can see in this example layering is also offered in this kernel but the increase in colors per scanline is minimal and it increases the flicker frequency. This was an elaboration on the score rendering approach which you see at the bottom with the 6 numerals that became a staple in 2600 games where score was the only stat required you could make the characters more fancy than the Playfield or Missiles would allow for.
Now I didn't put this here to scare you away from multiplexing your sprite objects beyond there default of 3 copies, I only wanted to express the costs involved with the maximum amount. Multiplexing sprites is a common practice in many 2600 games such as Ms Pac-Man & Jr Pac-Man which render there ghosts with minimal flicker unlike the crappy first effort in Pac-Man. So if you're careful and frugal with its use you can do a great many things.
Another common issue faced with only 2 actual sprites is the need for a 3rd or a 4th type per scan line where your only option for an additional independent sprite is to build a sprite manually using the 3 loose bits of 2 Missiles and Ball separately or together.
Based on this canvas you can make each bit object(Missile0/Missile1/Ball) 2, 4, 8, or 16 pixels wide but only one width setting per object per scan line, actually in code its much more efficient to set all 3 bit objects to one default width for every scan line jsyk. Each Missile provides 3 pixels each through copies and the Ball one pixel by default, multiplexing with flicker can extend the amount of Missile copies you can use but its far less reliable in cycle costs and on screen appearance(The flicker burns my eyes!
)than just sticking to the default. Unfortunately the Ball literally can not multiplex at all which has something to do with the hardware architecture, perhaps its loss on the 5200 and 7800 wasn't such a bad thing.
Its worth noting that the Player objects can be stretched too just like the 3 bit objects but unfortunately doing so cancels out its corresponding Missile and its ability to copy, yikes. To get around that the Ball is employed as the stretched Player objects projectile. Because of the Missile loss and copy cancellation I find this particular option unattractive to say the least but it has its uses within specific contexts(EG. The walker legs in Empire Strikes Back 2600.)
The major limiting factor of loose bit construction is that each bit has to be "tiled" with those damn color clock based gaps between each copy. Since that is so far apart we use the 3 bit objects and there copies at different horizontal alignments to compensate for that. Here I just show the default maximum number of copies but multiplexing with a moderate amount of flicker can extend the number of copies further IE. more than 3 Missile sprites per scanline. Also any bit constructed sprite has the same moving in unison gap distance requirement that the Player sprites do jsyk.
Something else I should warn you about bit constructed sprites is that they lack native hardware flopping, while the Player objects flop horizontally with a simple hardware setting switch the bit constructed sprites require separate Left & Right code kernels adding to the cycle overhead of using them.
Okay lets look at what we can build.
-In practice 1 bit is only capable of producing basic solid shapes through changing the bit width and horizontally offsetting the Bits position per scanline. Try to think of it like an Abacus with set distances between each bead where at its most basic a shape is split into 3 slices of Top, Middle, and Bottom.
-2 bits together is far more versatile when each is set to different widths per scan line. Something of note is that the 3 bit objects can overlap and occlude each other being on separate rendering layers which is handy for creating odd value widths more efficiently using 2 Bit Object widths rather than building a particular width with 3 different bits at 3 different widths butted directly against each other in horizontal alignment.
-3 bits is the easiest to use and has the fewest limitations especially in regards to non solid shapes and patterns. Most of the challenge is utilizing copy ability and trying to form the intended pattern.
-You can make center flopped sprites with the Player objects using both Players but that pretty much defeats the purpose of flopping in the first place. You can flop one Player object to create the other side but the mandatory distance between each copy requires a bit construct to fill the middle in.
-Generally speaking the 2 Missiles are your bread & butter when it comes to bit constructed sprites having a native copy limit of 3 and potential for multiplexing. The Ball is truly singular in use which is why Pitfall has a single swinging vine and Adventure has its single blocky knight. So in practice you could make a cursor, a simple main player sprite(Think Pac-Man), one additional sprite per vertical zone, a weapon for the main player with a distinct color,or to generically fill a portion or along a single edge of a Playfield graphic.
-One trick I forgot about is the use of very quick HMOVE functions applied to the sprite to streak in appearance odd value width sizes(EG. 3&6 wide pixels.) Basically by changing a pixels horizontal position every time the screen is rendered you can produce what appears to be a solid line(Bird in cage flicker.).
Don't get too excited about this function since its costly enough to invoke that its best to isolate its use to a few sparse places IE. using the Ball object to make one small odd value line segment width within a bit constructed sprite.
One thing I learned about bit objects on the 2600 is that it doesn't matter how big you make sprites just as long as you have enough bits to fill the distance.
-Boss Sprites can be rendered using the Playfield itself as the large scale of the pixel doesn't look out of scale. Moving a Playfield sprite on the 2600 is similar to how the Nes did big Boss sprites in that you blank the background color and pan or scroll the image to "move" the giant sprite. While vertical movement of the Boss sprite can be done cheaply horizontal Boss movement requires the use of all 3 loose bit objects to render approximate interim horizontal positions between each Playfield pixel width distance across the screen otherwise it moves jerky.
-Medium scale sprites vary in size potential but one thing is certain which is you're better off using 4 pixel wide line segments or wider to plot its overall design as you don't have enough loose bits to vary the outline shape and fill shapes to the same crispness of a Player object.
-Small scale doesn't need much description as its straight forward pixeling with the Player object.
Probably the easiest way to compose an Atari sprite with multiple layers or bits outside of the actual hardware implementation is to take advantage of whatever paint program you're using and put each distinct sprite object onto image layers which should help greatly to keep things organized and discrete especially in regard to overlapping. Also most have options for tile or stamping grids to set distances which should help with plotting out sprites and there copies.
In my next post I'll likely go into scan line isolation, using objects in different ways, and or multi-color issues. Till next time.