Comments on Chaos

Sean Irvine posted a comprehensive analysis of the Chaos code on comp.sys.sinclaur Usenet post, 13th December, 1996. It is reproduced here without permission.

Chaos Breakdown
Sean Irvine (sirv...@cs.waikato.ac.nz)

Dept. of Mathematics

University of Waikato

Private Bag 3105

Hamilton

NEW ZEALAND

There has been much reminiscing over the last year about the ZX Spectrum game "Chaos: Battle of the Wizards" (Julian Gollop, Games Workshop, 1984) in a variety of forums. This role-playing game spurned the sequel "Lords of Chaos" on a number of platforms, but many people continued to yearn for clones more like the original for other platforms. Recently a clone for PC was produced called Morkin2, there is also rumoured to be a clone for the Atari ST. I have never seen either of these clones and so cannot comment on them. I am the author of a clone for the Commodore Amiga, and I'll say a little bit about my clone towards the end.

In writing the clone (and even before then) I disassembled various parts of the Spectrum Chaos and thereby obtained considerable detail about its operation, and this I believe gives me the qualification to make some comments about Chaos. I should say that I have never spoken to Julian Gollop about any of the things included here, so a few things are just mere speculation on my part. Further, most of the effort was carried out several years ago, and as such my memory is a little hazy about a few of the details. In particular I can clarify the situation with regard to a few pieces of folklore (like the unused sprites and spells) and introduce some new bits and pieces that I have not previously seen in the literature.

I used to play Chaos extensively on the Spectrum with my brothers. However, we always wanted to play longer and longer versions of the game. To this end we proclaimed a number of `house rules' like `thou shall not kill a human wizard until all its creations have been killed' in an effort to make the game last longer. Unfortunately, this caused most games to result in a draw, and led me to make my first hacks in the Chaos code. It was a trivial matter to alter the code so that we could restart the game and continue on from where we left off. Then we had the perennial problem that fire would engulf the entire screen, so I wrote an editor which enabled the contents of the screen to be altered. The editor also allowed one to change the number of spells allocated at the outset and other things of a similar vain. The mechanism for some of these will be discussed below. I'm not exactly sure what happened to my fabled editor, it is probably collecting dust in some remote corner of a closet in my parent's house; but if I ever find it I will upload it to a suitable site.

There is another editor distributed with Emulate magazine that allows inspection and alteration of graphics and text within Chaos.

Some parts of this document are necessarily technical. Remember when attempting any of the hacks suggested here that you should probably work on a copy of Chaos, so that you can resurrect the original game when required.

Anyway the purpose of this article is to describe in detail some of the inner workings of Chaos, and a nice easy place to start is with the sprites and the observation of sprites in the code which are not used in the game. The addresses I give are in decimal.

Sprites
The sprites are dispersed at a number of locations in the code as listed below. Each sprite is coded as four characters in the usual UDG method.

32551: The graphic for the [S] cursor. 32944: The graphics for modified wizards, including wizards with magic swords, bows, knives, shields, armour, and wings. 41484: The twirl used during casting. 41797: Explosion effect. 48951: Attack effect, exploding circle. 49443: Result of dragon breath effect. 49981: Various cursors (empty box, wings, and arrows). 60241: Graphics for the creatures and other objects like wall, note this continues all the way to 64820 where the wizard descriptions begin. 64820: Start of the graphics for the eight different wizards.

The character set information starts at 55560. PostScript images of all the sprites in Chaos are available on my web page: http://www.cs.waikato.ac.nz/~sirvine/

As has been noted by several people there are a number of graphics in here which do not appear in the actual game. In particular their are the infamous troll graphics at 62515, 62547, 62579, 625747, and 62611. There is also a graphic for a dead vampire (in the game undead's never result in corpses) at 61331 and for what can only be described as dead gooey blob at 60627. This can actually be verified by forcing a piece of this stuff onto the screen where it will then sprout living pieces of blob. Each creature has either one (e.g. spectre), three or four images. There is also what must be a dead image for a spectre which again never occurs in the game.

A table starting at ~58436 gives the name, statistics, and location of the sprites for each object in the game. Entries are of variable length and give first the name, then the stats, the five lots of 3 bytes that describe the image location (machine address) and attribute to use for that image. Note that this table is not in the same order as the actual internal order used by the rest of the program. In particular, this table does contain an entry for the troll which is never used anywhere else in the program. A typical entry is shown below (from address 59371):

SKELETON     3 5 0 2 1 3 4 6 255 17 63284 71 63316 71 63348 71 63316 71

This gives the information for a skeleton and indicates that all its sprites should be drawn with attribute 71 (bright white) and that its image data is located at 63284, 63316, 63348 and 63316.

For the sake of completeness I include the relevant statistics here for your reference. The columns of numbers are: combat, ranged combat, range, defence, movement allowance, magical resistance, manoeuvre, ???, law/chaos rating, overall strength (?).

0 Nothing 1 Nothing 2 King Cobra      4 0 0 1 1 6 1 8  1 30 3 Dire Wolf       3 0 0 2 3 7 2 8 -1 12 4 Goblin          2 0 0 4 1 4 4 8 -1 12 5 Crocodile       5 0 0 6 1 2 2 7  0 34 6 Faun            3 0 0 2 1 7 8 7 -1 20 7 Lion            6 0 0 4 4 8 3 5  1 38 8 Elf             1 2 6 2 1 5 7 6  2 26 9 Orc             2 0 0 1 1 4 4 9 -1 21 10 Bear           6 0 0 7 2 6 2 5  1 23 11 Gorilla        6 0 0 5 1 4 2 6  0 18 12 Ogre           4 0 0 7 1 3 6 6 -1 23 13 Hydra          7 0 0 8 1 4 6 4 -1 36 14 Giant Rat      1 0 0 1 3 8 2 9  0 13 15 Giant          9 0 0 7 2 6 5 3  1 23 16 Horse          1 0 0 3 4 8 1 8  1 21 17 Unicorn        5 0 0 4 4 9 7 5  2 16 18 Centaur        1 2 4 3 4 5 5 6  1 23 19 Pegasus        2 0 0 4 5 6 7 5  2 16 20 Gryphon        3 0 0 5 5 5 6 5  1 10 21 Manticore      3 1 3 6 5 6 8 3 -1 13 22 Bat            1 0 0 1 5 9 4 7 -1  8 23 Green Dragon   5 4 6 8 3 4 4 0 -1 32 24 Red Dragon     7 3 5 9 3 4 5 0 -2 34 25 Golden Dragon  9 5 4 9 3 5 5 0  2 27 26 Harpy          4 0 0 2 5 8 5 5 -1 13 27 Eagle          3 0 0 3 6 8 2 6  1 14 28 Vampire        6 0 0 8 4 6 5 1 -2 40 29 Ghost          1 0 0 3 2 9 6 4 -1 15 30 Spectre        4 0 0 2 1 6 4 5 -1 15 31 Wraith         5 0 0 5 2 4 5 4 -1 10 32 Skeleton       3 0 0 2 1 3 4 6 -1 17 33 Zombie         1 0 0 1 1 2 3 4 -1 25 34 Blob           1 0 0 0 0 0 0 0  0 40 35 Fire           0 0 0 0 0 0 0 0  0 12 36 Magic Wood     0 0 0 5 0 0 9 6  2 250 37 Shadow Wood    2 0 0 4 0 0 9 4 -2 30 38 Magic Castle   0 0 0 0 0 0 0 0  0 50 39 Dark Citadel   0 0 0 0 0 0 0 0  0 50 40 Wall           0 0 0 0 0 0 0 0  0 30 41 Wizard1 42 Wizard2 43 Wizard3 44 Wizard4 45 Wizard5 46 Wizard6 47 Wizard7 48 Wizard8

Notice the careful ordering of this table with all the flying creatures grouped together, all the mounts grouped together, and all the undead creatures grouped together. This leads to numerous simplifications in the coding of the game, that are best appreciated by delving into the code itself.

Text Messages
Apart from the names of the creatures and wizards there are two other groups of text messages in Chaos. These start at locations 34905 and 53195 respectively. A table starting at 34825 gives the addresses and lengths for the first set of messages, a similar table starting at 52691 gives the same information for the second group of messages. The actual subroutines to print these messages are found at 34799 and 47867. When called BC holds the screen address and A holds the message number.

The messages in the first group are:

CHAOS -THE BATTLE OF WIZARDS By Julian Gollop How many wizards? (Press 1 to 8) PLAYER Computer controlled? YES NO Level of computer wizards? Enter name (12 letters max.) (Press Y or N) Which colour? Which character? 1  2   3   4   5   6   7   8 (Press 2 to 8) NEW SPELL FOR THE CONTEST IS DRAWN BETWEEN THE WINNER IS: ^^^^^^^^^^^^^^^^^

The messages in the second group are (the numbers are the internal code for the message):

0--47  49 (ASLEEP) 50 (DEAD) 51 DISMOUNT WIZARD? (Y OR N) 52 ENGAGED TO ENEMY 53 OUT OF RANGE 54 (FLYING) 55 'S TURN 56 MOVEMENT POINTS LEFT= 57 UNDEAD-CANNOT BE ATTACKED MOVEMENT 58 RANGE= 59 RANGED COMBAT,RANGE= 60 NO LINE OF SIGHT 61 PRESS ANY KEY 62 KNIFE 63 SWORD 64 ARMOUR 65 SHIELD 66 FLYING 67 SHADOW 68 MOUNT 69 UNDEAD 70 (CHAOS 71 (LAW 72 COMBAT= 73 RANGED COMBAT= 74 RANGE= 75 DEFENCE= 76 MOVEMENT ALLOWANCE= 77 MANOEUVRE RATING= 78 MAGIC RESISTANCE= 79 CASTING CHANCE= 80 10 81 SPELLS= 82 ABILITY= 83 'S SPELLS 84 SPELL FAILS 85 SPELL SUCCEEDS 86 IS THE WINNER 87 PRESS KEYS 1 TO 4 88 PRESS '0' TO RETURN TO MAIN MENU 89 1.EXAMINE SPELLS 90 2.SELECT SPELL 91 3.EXAMINE BOARD 92 4.CONTINUE WITH GAME 93 DISBELIEVE 94 ILLUSION? (PRESS Y OR N) 95 'S CREATIONS 96 MAGIC FIRE 97 GOOEY BLOB 98 LIGHTNING 99 VENGEANCE 100 DARK POWER 101 DECREE 102 JUSTICE 103 LAW-1 104 LAW-2 105 CHAOS-1 106 CHAOS-2 107 MAGIC SHIELD 108 MAGIC ARMOUR 109 MAGIC SWORD 110 MAGIC KNIFE 111 MAGIC BOW 112 BLIND 113 MAGIC BOLT 114 TEMPEST 115 RAISE DEAD 116 TELEPORT 117 SUBVERSION 118 TURMOIL 119 DEAD REVENGE 120 CONSECRATION 121 DISPEL 122 COUNTER SPELL 123 MAGIC WINGS 124 MAGIC SLEEP 125 SHADOW FORM

Internally these are numbered starting at zero, but because of the objects in the game taking the first 48 positions the message (ASLEEP) is code 49, (DEAD) is code 50, etc. As far as I know the messages (ASLEEP), BLIND, TEMPEST, TELEPORT, DEAD REVENGE, CONSEC- RATION, DISPEL, COUNTER SPELL, and MAGIC SLEEP do not occur in playing the game. The (ASLEEP) can be made to appear by fiddling with the owner table as described further below.

This finishes the discussion of what one might expect to discover after a few hours of hacking around in the code. I will now move onto some more advanced material.

Spells
There is a table which starts at 32096 which consists of a series of 7 byte records in the format: internal object number, ?(1), twice the maximum cast distance, effect on chaos/law indicator, ?, address of routine to cast this spell:

32096 93 9 255 0  0 Disbelieve 32103  2 8 3   1 18 CreatureCast 32110  3 8 3  -1 18 CreatureCast 32117  4 8 3  -1 18 CreatureCast 32124  5 7 3   0 18 CreatureCast 32131  6 7 3  -1 18 CreatureCast 32138  7 5 3   1 18 CreatureCast 32145  8 6 3   2 18 CreatureCast 32152  9 9 3  -1 18 CreatureCast 32159 10 5 3   1 18 CreatureCast 32166 11 6 3   0 18 CreatureCast 32173 12 6 3  -1 18 CreatureCast 32180 13 4 3  -1 18 CreatureCast 32187 14 9 3   0 18 CreatureCast 32194 15 3 3   1 18 CreatureCast 32201 16 8 3   1 18 CreatureCast 32208 17 5 3   2 18 CreatureCast 32215 18 6 3   1 18 CreatureCast 32222 19 5 3   2 18 CreatureCast 32229 20 5 3   1 18 CreatureCast 32236 21 3 3  -1 18 CreatureCast 32243 22 7 3  -1 18 CreatureCast 32250 23 0 3  -1 18 CreatureCast 32257 24 0 3  -1 18 CreatureCast 32264 25 0 3   2 18 CreatureCast 32271 26 5 3  -1 18 CreatureCast 32278 27 6 3   1 18 CreatureCast 32285 28 1 3  -2 18 CreatureCast 32292 29 4 3  -1 18 CreatureCast 32299 30 5 3  -1 18 CreatureCast 32306 31 4 3  -1 18 CreatureCast 32313 32 6 3  -1 18 CreatureCast 32320 33 8 3  -1 18 CreatureCast 32327 97 8 13 -1 18 CreatureCast 32334 96 7 13 -1 18 CreatureCast 32341 36 7 17  1 17 Trees&Castles 32348 37 3 17 -1 18 Trees&Castles 32355 38 4 17  1 23 Trees&Castles 32362 39 4 17 -1 23 Trees&Castles 32369 40 7 13  0 12 Wall 32376 112 9 13 0 18 Lightning 32383 112 9 13 0 18 Lightning 32390 98 9 9   0 18 Lightning 32397 98 9 9   0 18 Lightning 32404 99 7 30 -1 12 DarkPowerEtc 32411 101 7 30 1 12 DarkPowerEtc 32418 100 4 30 -2 11 DarkPowerEtc 32425 102 4 30 2 11 DarkPowerEtc 32432 107 6 0  1 23 MagicShield 32439 108 3 0  1 23 MagicArmour 32446 109 3 0  1 16 MagicSword 32453 110 6 0  1 16 MagicKnife 32460 111 4 0  1 17 MagicBow 32467 123 4 0  0 14 MagicWings 32474 103 7 0  2 5  ChaosOrLawSpell 32481 104 5 0  4 6  ChaosOrLawSpell 32488 105 7 0 -2 5  ChaosOrLawSpell 32495 106 5 0 -4 6  ChaosOrLawSpell 32502 125 6 0  0 18 ShadowForm 32509 117 9 15 0 18 Subversion 32516 117 9 15 0 18 Subversion 32523 115 4 9 -1 18 RaiseDead 32530 115 4 9 -1 18 RaiseDead 32537 118 9 20 -1 17 Turmoil 32544 118 9 20 -1 17 Turmoil

The second field could perhaps have something to do with the colour of the spell? I am unsure what the fifth column could be for.

Other important addresses: 35241 (level of computer players), 37203 (current chaos/law indicator), 37221 (spell success flag), 37755 (spell selected), 38862 (number of attempts for current spell, e.g. =4 for a wall spell), (44050--3) position of cursor on board.

Object Tables
The main state information of the game is stored in a series of 320 byte tables starting at 57375. The first table contains the object code for the item in each cell of the screen. The second table is for ?. The third table contains the current animation value. The fourth table contains the owner numbers. Each table also contains space for objects in what is normally the border.

In the animation table value 0 to 3 are the position in the animation sequence, 4 is the corpse, and 5 is for asleep (?).

Game Startup
The BASIC program starts Chaos by jumping to location 32000, but in fact the first instruction executed there is merely a jump to 35321 where the real initialization begins. Roughly, speaking the initialization runs as follows:

i) Make border blacks and set up ATTR_T, ATTR_P, MASK_P, and PFLAG system variables.

ii) Disable interrupts.

iii) Clear the screen.

iv) Clear various buffers (by replacing all memory from 35344 through to 35395 the game can be made to continue from its previous state).

v) Welcome screen, input number of players and wizard level.

vi) Input each players name in turn, choose sprites.

...

(I never got much further, but presumably there is some initialization for spells that follows here somewhere.)

Miscellaneous Routines
The following are for the most part not very useful to use from basic since they assume all sorts of things about the registers, interrupts, etc. But I include them here to aid anybody else trying to hack parts of chaos.

33536 Gets the address of the wizard name buffer of the current player. 34543 Start point of the turmoil routine. Maybe someone else could examine this     and determine why it causes the game to crash sometimes. 35248 Input a number from the keyboard.

36762 Routine to check for new spells.

36939 Random number generator (?) [the last random number produced is stored at 36986]

37104 Draw a wizard. 38819 Test if a spell cast succeeded. 38842 Print message saying spell succeeded. 39285 Main casting routine for creatures. 40784 Grow gooey blobs and fires. 47854 Print text of length E from HL to BC. 47867 Print a message from the second set. 47959 Draw the border. 48278 Handle the I key and numbers. 48855 Blank the bottom of the screen. 50099 Information routine. 50670 Clear screen. 57103 Master printing routine 57166 Print given object. 57202 Update the screen. 65110 Set standard ROM interrupts. 65120 Set game interrupts (animate the screen). It is quite cool to actually do a RANDOMIZE USR 65120 while in BASIC, you then get Chaos animating the screen over BASIC, quite freaky.

Miscellaneous Pokes
These are easily done using a Multiface 2 or with some emulators. However, it is possible to make these pokes by loading Chaos and not letting it run or alternatively by playing the game once and then pressing BREAK while the winner/loser screen is shown. You should then POKE 23606,0; POKE 23607,60 to invoke the standard character set. Once you have made the desired pokes, you can start the game by RANDOMIZE USR 32000.

The following is a collection of addresses and what to put there to cause various effects where x denotes any sensible code.

34171,x:  Maximum object code which can be subverted + 1, standard value = GooeyBlob. Putting 1 here will make subversion impossible. 34543,201: Disable the turmoil spell (?). 36239,x   First spell (disbelieve by default). 39286,x:  Number of creatures per cast. 39646,x:  Number of trees per cast. 39659,x:  Number of castles per cast. 39799,x:  Number of pieces of wall per spell. 40120,x:  Maximum object code hitable with lightning (?). 40444,x:  Number of attempts for Decree and Vengeance. 40455,x:  Number of attempts for Justice and dark power.

36173,0; 36178,x: Force each player to have x spells at the start of the game. Last spell is infinite for x > 21.

36173,21; 36178,20: Normal spell allocation.

36194,5; 36232,12; 36186,0: Make all spells white all the time.

Note: I have not tried those marked (?), but for theoretical reasons I expect they should work.

Hints to Hackers
There are several general techniques which have proven useful in hacking Chaos. Firstly, look for instructions of the form CP x, where x is a valid creature code. In this way it is quite easy to track down all those areas of code potentially related to, for example, the shadow wood.

Similarly, look for instructions of the form LD A, x and a nearby call to a print routine. These enable one to locate code associated with any particular message.

For example searching for a LD A,94 instruction (which might have to do with "ILLUSION Y/N") yields a few likely candidates. In fact the relevant occurrence is at 38021. About here is where the program ask you whether or not you want and illusion. By replacing the instruction at 38032 with LD A,"N"; NOP you can prevent the game from ever asking this question.

Amiga Chaos
As promised at the beginning of this document, I will say a little bit about the clone of Chaos that I have written for the Amiga. In my clone I have tried to preserve the gameplay of the original version, and the clone supports all the spells of the original, except the relatively stupid Chaos and Law spells, and the Shadow Form spell. But, the number of spells has been greatly expanded, there are currently over 150 spells. They include my interpretations of the Sleep, Tempest, Teleport, and many other novel spells. Oh, and I have a troll as well (along with many other new creatures).

I have retained 16 by 16 pixel imagery for the sprites, but made the board slightly larger than the original chaos. The original shapes of most sprites have been retained, but have been enhanced with additional colour, so that each creature is now multi-coloured.

In addition there is a team play system and independent creatures.

If you own an Amiga and don't already have my clone then you can obtain it off any one of the Aminet ftp sites. A PostScript manual for the game (including full details of all the spells is available on my web page, http://www.cs.waikato.ac.nz/~sirvine/).

If anyone wants to make a serious attempt at porting my Chaos clone to other platforms I will make my source code available to them. Currently the source is about 1 MB of C code, but does not rely heavily on custom Amiga graphics chips, which should alleviate some of the difficulties in porting to other systems.