This was reality in my childhood. If you didn't have the money for commercial software, you typed in code from magazines. Most magazines also offered the listings on cassette tapes or floppy disks, but it wasn't cheap (for the period).

The worst to type in (and the checksum programs were best for this - though strangely, as a kid I never understood their purpose, and never used them!) were machine code loader programs. These were typically graphics utilities, sound generation utilities, or games. Essentially they consisted of a simple "loading loop" (either a FOR-NEXT or a GOTO style loop) in which data values were read and POKE'd into memory. For instance, such a loop would look like this:

10 I=&H0000:READ X:IF X=-1 THEN STOP:POKE I,X:I=I+1:GOTO 10

Now - I took out some of the spacing to make it somewhat readable, in real life, that would have been mashed even more, because you needed as much space as possible. The variable "I" would be the starting memory address of where the ML code would be POKE'd into memory, each value would be read into "X", POKE'd into memory, and "I" would be incremented and it would continue, until "X" was read as a -1 to stop the process.

Following this loader would be a super-long series of DATA statements:

20 DATA 20, 1000, 1478, ..., 52, 780, 21, ..., etc

...insert several hundred more DATA statements here...

9999 DATA 40, 71, ..., etc, -1

These were typically decimal values, as using hex values would consume more memory for the additional "&H" prefix (though there were loaders that would use strings to prefix the value, then convert back, etc before POKE-ing the value - the loaders could and did get very sophisticated). Also, again I spaced the values in the DATA statements out for readability - in real life they'd have been mashed together for memory space reasons.

So imagine typing page after page after page of these DATA statements in, numbers, commas, checking each line as you went to make sure you typed it in correctly. Then, you get to the end, and what do you do?

Well - those who were waaay too impatient would just type RUN:EXEC and hope - which was stupid, as these ML programs would typically either relocate themselves to where BASIC resided, or do other nastiness, and you'd never be able to save the code.

So - the smart thing was to save the listing to floppy or tape - then run it. You'd run it, then when it was done POKE-ing the values into memory, you'd execute it (different machines had different methods of doing this - on the Color Computer, which I am most familiar with as it was the machine I had as a kid, you'd RUN the code, then type EXEC - sometimes followed by an address value, depending on where the code starting memory pointer was set).

And it would crash the machine, or fail in some other way. Maybe you fat-fingered a double comma, or added an extra zero in the values (several no-op (NOP) codes in row, usually represented by 0 values - were not uncommon). Or maybe you typed a 4 when it should have been a 5 - or any number of equally bad options.

So it crashes - now what do you do? Welp, break out that magazine, and start scanning each line in your listing, and compare it with the lines in the magazine, and pray you find the problem. You could easily be there for hours. This kind of thing could stretch into days of work, if the program was especially sophisticated. But what you could get in the end...

...amazing games!

...new BASIC commands!

...new graphic routines!

...better sounds!

...all of these and more at the same time!

There really isn't anything comparable to it today; on one hand, that's a good thing. On the other, though, it isn't - these offerings tested your skills, patience, and anger-management. Those who were masters of such gained valuable lessons...