I fear them. Not obvious bugs, but the sneaky ones—the ones where your code will compile and run just fine, where the program can pass all the tests you thought of; but there it sits—the bug you didn’t think of testing for.
Last week I got back to working on my experiment with AI, artificial life, and digital organisms. I got the figures to the point where the next bit would be all about experimenting with larger populations, modifying their behavior, and training them to solve problems. Basically, I thought all the fun parts were next.
Unfortunately, the very next day, when I went to do one of the fun parts, I found out that the way I was saving a population and restoring them was killing them. If I saved a population to a file, even if they could normally produce millions of children, when I restored them from the file, everybody died.
The problem was easy to find, but tedious to fix. I made notes of the trouble and how to deal with it, and set the project aside for about a month and a half. Of course, the research continued, and I got to play with my robo-eye, the vOICe.
On Monday I picked up my notes and figured out how to get back to it. By Tuesday I’d fixed save and restore, Wednesday my brother and I recorded the last episode, and yesterday, I tested and debugged what I’d done on Tuesday. I’d finished a day sooner than I expected, and was feeling all sorts of productive. This morning, I was about to implement one of the fun bits.
Before I got into it, I rather idly looked at the tests I’d run on save and restore. That’s when I noticed. The otherAddress field wasn’t getting updated by internal i/o calls.
I call my digital creatures “figures.” Each figure can read and write to the other figures that live in the same environment, a little world I built them called the “realm.” That’s their internal I/O—the input and output they can get from each other.
Whenever one figure reads from or writes to another one, the figure being read from or written to is meant to get a hook to the figure that is doing the reading or writing. If one figure messes with another, the one being messed with notices and remembers who done it. The address of the figure that was reading or writing to you should be stored in your otherAddress field.
For testing, there are only three spaces in the realm, and only two figures alive at once. Whenever a third figure is born, the oldest figure dies. To be certain save and restore were working write, I listed all the fields of the figures, as they were being saved, and again as they were being restored. All the fields matched, every number was the same before saving and after restoring. Unfortunately, I noticed that the otherAddress field never ever pointed to the other figure.
I am truly grateful that I noticed. I’d had to rework the internal i/o quite a while back. I looked over the code and I had just forgotten to update the field. The thing is, that particular mistake has been there for weeks and months, and I never noticed. What other sneaky little bugs might be buzzing around in my system?