I was really really into the GameShark during the PSX days. The original one was nice, but the best thing was the GameShark Pro, which allowed you to (amongst other things) generate your own codes via a rudimentary hex editor/comparison tool that could be invoked by pressing a button on the device. (You could also connect it to a Windows PC via a parallel port on the back, which was tedious, but the accompanying software was easier to work with.)

So to create (e.g.) an infinite-ammo code, you would reload so that you had a full magazine of 30 rounds, and press the button. Then you'd have the GameShark search for addresses with a value of 30. Usually it'd return a huge amount of mostly garbage, so then you'd return to the game, shoot once or twice to change the number of rounds, and go back and tell it to narrow the results down by showing only the addresses that had changed to 29 or whatever.

After doing that two or three times, you'd have a working code that you could save to the device or share with people.

Sometimes it wasn't obvious what the value of a variable was, so you'd have to do a 'not equals' search. So to get weapon values, you would equip a knife, do a search, change to a hand gun, do a 'not equals' search, usually repeat that many times (because there are always going to be things changing) until you finally end up with an address that specifies the weapon (and sometimes one or two accompanying addresses).

Firstly, by watching the value of these addresses (you could always return to the results screen and see what the new value was), you would find out which values correspond to which guns. The knife might be 01, the hand gun 02, the rocket launcher 0A, and so on. That would allow you to take the address and create many codes for different weapons by adjusting the values.

More humorously: In some games, like Resident Evil, the address for the weapon function would be accompanied by another address for the weapon ammo. You could adjust the two values so that they differed from each other — for example, set the function to 01 and the ammo to 0A — and then you would end up with a knife that shoots rockets.

The codes that were the most challenging to create, and also probably the most fun, were what i used to call 'abusive codes'. Abusive codes were usually more humorous than practical — instead of giving you useful things like infinite ammo or lives, abusive codes would screw with the game's display or physics.

One of my favourite abusive codes was roller-skate mode for Silent Hill. Silent Hill is an extremely frightening and morbid horror game (i still can't play it alone), and enabling roller-skate mode completely changed the dynamic. First of all, during game-play, Harry's legs wouldn't move — he would just scoot around like he was sliding on ice. What was funnier, though, was that the sliding would persist into the game's cut scenes (which usually involved the discovery of something gruesome). So for example Harry would come across some mutilated corpse, the music would get all shrieky and he would exclaim how terrible it was, and all the while he would be scooting all over the screen. It turned the game from something frightening into something hilarious.

Most of the other abusive codes that i and my friends experimented with had similar effects on the physics. For example, in Resident Evil 2, we created a code where, if you pressed a certain button on the controller, the characters legs would shoot around like a helicopter and, if you held it long enough, they would gradually 'fly' up through the ceiling and off the screen.

Other games would allow you to alter aspects of the display. You could make the characters into giants, or make specific body parts extremely large or small, or make all of the doors turn into different objects. This was 'after my time', so to speak, but one of the Resident Evil games for GameCube allowed you to adjust the main character's breast size. If you cranked the value high enough, you could make her boobs fill the entire screen.