Archive for July, 2004
Productive
9,772 words now. That makes today very productive, since it means I’ve written more than five and a half thousand words since this morning.
Yesterdays problem was thinking of the right metaphors to describe basic language features, today the problem was coming up with simple code examples to demonstrate them. It sounds like an easy thing to do, but coming up with a three or four line example script that shows the usage of "and" and "or" in an if statement is a bigger challenge than I expected.
I’m getting into the more complex topics now, like references, functions and objects, so tomorrow should be harder still. The documentation is aimed at beginner and expert programmers alike, so I try and describe everything in as basic terms as I can. But I’m not sure of a real world metaphor for references.
Unless I start talking about cardboard boxes having magic portals of swirling energy connecting them together.
Written
4,000 words of documentation and counting.
So I’m all written out.
Anything
"I always felt insecure and in the way - but most of all I felt scared. I guess I wanted love more than anything else in the world."
- Marilyn Monroe
Topping
*yawn*
Saw the Bourne Supremacy (IMDB) tonight. Excellent stuff, although it did seem to wrap up pretty quickly, I kinda blinked three-quarters of the way through and all of a sudden it was over.
No Bearthing tonight, just RealLife(tm) work on some large databases (5 million rows going on 10). Hopefully that’ll be completed enough during work tomorrow that I can forget about it again and get back to all things Bear.
On a completely unrelated note, Sainsbury’s new chocolate cake is great. Although I’m sure it’s made by Lightbody’s and is the same as the Safeway one with a different topping. But neverless, I don’t recommend you eat more than half of one in a single sitting.
Human
Up until about 10:30pm I had no working internet connection. This makes me sad. And lost. And confused.
I mean, what do you do? Everything I could think of doing on the computer required connectivity. An internet connection is a basic human right, along with food, air, and shelter. It should be installed in homes at the same time as electricity and water. Do you ever move into a house without running water? Of course not, so why without a 10Mbps pipe to the world?
Of course, once I got it back, I still didn’t know what to do. As we all know, there’s nothing good on the internet.
Complex
It has been a productive weekend, with Bearscript gaining in functionality on an almost hourly basis. I’m hesitant to say that it’s finished, because I know that I’m going to be continually adding new objects and increasing the functionality of the existing ones, but I certainly believe that the root language is now at 100%. So let me just jump in the air.
… leap
Anyway, I continued today with subroutines, making sure that all variables were local in scope. Yes, this is a language without globals. If you want a custom subroutine to access a variable from the outside, you must pass it in, most likely by reference (which is like passing the box, rather than what’s in the box). This should make code more readable and more maintainable, and means that subroutines should be interchangeable with less worry they’re going to break something around it (which is important, as you will see).
Then I moved onto complex data-structures, which led me to open up the interfaces to the variable, array, and keyarray objects. Originally there was a compiler-level only interface to these, meaning you couldn’t access their methods directly, only via an existing variable, array or keyarray object. By opening up the interfaces to them it allows you to create arrays and keyarrays anonymously, as well as extract them from references. All this results in the ability to have arrays of keyarrays. Or keyarrays of arrays of arrays of keyarrays. Or whatever.
The most common use for this is an array of keyarrays. This would be used when you had data like contact information, where you had 400 contacts (the array), and each of them had 10 different fields you stored about them (the keyarray). Example…
contacts = new array (
keyarray.create(”name” => “richard”, “location” => “hamilton”),
keyarray.create(”name” => “chris”, “location” => “calgary”)
)
foreach person in contacts
output person.name & ” lives in ” & person.location & “\n”
next
The result of which would be…
richard lives in hamilton
chris lives in calgary
This sets up an array which contains two values, each of which is an anonymous keyarray. The loop then goes through all the items in the array and prints out the specfied values from the keyarray contained within. The code is guessing that because the variable called person is a normal variable created in the foreach line (and not an array or keyarray) that when you use it as person.name, that person must be a reference to a keyarray. You can remove the ambiguity by doing…
output keyarray.value(person, “name”) & ” lives in ” & keyarray.value(person, “location”) & “\n”
Where you’re specifically telling it to take the "name" value from the keyarray referenced by person.
Anyway, that’s enough of the Bearscript lessons from me for the night. But it’s good practice, as tomorrow I get to start working on the documentation again.
UPDATE: I just wanted to add something briefly about how forgiving Bearscript is about whitespace…
foreach person in contacts
output person
.name& ” in ”
& person.location&”\n”next
Yes. That works.
Wistful
Coding is a lonely experience. And after 11 solid hours of doing just that, in which I brought the Bearscript completion meter back up to 98%, it is this I feel more than anything. More than the sense of achievement. More than the sense of pride that what I’ve written works. More than the sense that completion of the entire Bearthing project is one step closer, especially important with less than two months left before the deadline.
BBC documentaries with Michael Palin and nerdy scientists playing on the iMac to my left have kept me entertained and educated, while Chris has given me a slightly more personal level of contact, even it’s one still seperated by keyboards and 5,000 miles.
As the time approaches 5am on Sunday morning (ignore the time it says I posted this, it’s lying), my mind has slipped from coding completely, focussing me instead on just how quiet it is in here. Sure, there’s the constant hum of PC hardware, but I’ve become so used to that in my daily life that I almost don’t hear them unless I really pay attention.
Sitting in silence, with nothing to truely occupy my mind, it skips playfully through different thoughts. Some are imaginative, creative, the product of a mind that wants to try so many things, but which often can’t muster enough motivation in the rest of the body to do them. Others are regretful, sad, wistful of better times when it wasn’t as quiet, when I wasn’t quite so lonely.
Tomorrow I’ll try and complete that final 2%, making sure that all my test scripts still work, even when the entire variable and subroutine infrastructure has been changed and re-written. I’ll also take a look at integrating the language with the front and back-end systems, and start to think about how Bearscript written admin code interfaces with the Perl written stuff.
Hopefully that’ll be enough to make me believe the silence is a loud one.
Anniversary
I’ve sat here for half an hour, and I really can’t think of anything apart from how I should really be in bed.
Mighty
I’m currently sitting in front of a PC which only just meets the minimum specs for the upcoming Doom 3. Graphics card wise I’m doing not bad (I’m a couple of generations behind with a Radeon 9700 Pro) but processor wise I’m down at 1.7Ghz (half the speed of what is now available).
This means that I’ve been looking at various upgrade paths over the last week, but I’m unable to make a decision about any of them. I always believe that you should buy the absolutely best available at time of purchase, so as to give the widest gap between each upgrade as possible. Which means an X800 PE, and a 3.4GHz Pentium 4. Right now that runs at almost a grand, which makes me start thinking whether I should be doing a bigger upgrade and changing everything in one go. Alienware machines look mighty sexy, and Overclockers do a nice line of pre-built machines for around £1,400 too. Normally I would build my own, but I’m not sure if I can be bothered with the hassle this time.
I’ve also looked at the Apple Powermac G5, because I would get a 20% discount. And I’d fund the extra by selling my iMac. But I’m not sure whether I’d want to dump the PC completely, and I could use the price difference between the PC and Mac options to buy a good LCD display (or two) instead.
Oh decisions.
Shame
I could write about how I didn’t take my medication last night to see what difference it would make to me today, and how I didn’t have to go for a nap after work for the first time in a month (usually I just can’t hold myself up once I get home). But I won’t.
I could write about how I started to convert Bearscript tonight to handle variables in a different way so that I could get that final 1% done, but how my head just wasn’t wrapping itself around the problem, making it difficult to make any progress. But I won’t.
I could write about how I spent a good while making up another compilation CD to put into the car, and how hard it is to choose 18 good songs out of my 10,000 track collection. This is because there is so much stuff in there that I like and because I’m trying to pick music that is good for driving and isn’t something I would normally hear (which means no Ben Folds!). But I won’t.
I could write about how I’m getting more and more addicted to Galaga, and how often I look at the flat trying to find somewhere I could fit a full size original arcade machine. But I won’t.
Instead I’m going to write about…
Oh, look at that, I’m out of time. Shame.
Inconsistency
It appears that despite my best efforts, Bearscript sucks.
Ok, that’s a bit harsh. But it sure isn’t right. As I said last night, I want to remove as much inconsistency as possible, which means that in every situation, I have to guess exactly what it is you want to do with the variable you just named.
A lot of the time, that’s fairly straightforward. But when you start passing variables back and forth to subroutines, a variable has to be one thing one minute, and something entirely the different the next. And at the moment, my language structure just can’t support that. I’ve tried working around it, but it doesn’t make any difference, I’m going to have to completely re-think how all variables are stored.
So now I’ve got a language that earlier this evening was 99% complete, but is now just 60% complete. Now I get the fun of breaking everything that already works and re-coding it all just so that final 1% works.
I guess I should re-evaluate everything else while I’m at it, just so I don’t arrive at this situation again.
Ambiguity
I actually did do what I set out to do today and implemented the Bearthing table structure that I drew out on paper yesterday. I’m reasonably happy with it, but in doing so I just raised a whole load of new questions with myself about what is the right way to approach things. I can easily create a system which will work, and allow me to develop all the services I want, but the trick is making a system which will also be understood and easily expandable by others. I think perhaps I’m not 100% sure of anything yet.
After doing that I turned my attention to the language again, and started to firm up various details. Mostly today that was to do with the difference between local and global variables, plus the details of what is actually passed to a subroutine. I’m trying to remove as much ambiguity as possible by making the interpreter work out exactly what it is you’re trying to do, I don’t want you to have to manually specify what is local, what is global and have you guessing what will happen when you change a variable in a subroutine.
My feeling is that any variable used within a subroutine is automatically local to it, and that it can only get access to outside variables if they have been explicitly passed in. But exactly WHAT gets passed when you give arguments to a subroutine? Is it the actual variable/array/keyarray itself? So that when the subroutine modifies it, the original (the value outside the sub) is being changed as well. Or is it a copy of the variable/array/keyarray, so that changing it makes no difference to the original?
At the moment I have it setup to be the former, but I can see situations when you’d want it to be the latter. I’ve also considered that variables get passed as a copy, but array’s and keyarray’s get passed as themselves, although this seems like an inconsistency of the type I’m trying to avoid. There is the possibility I could make it an option on a per argument basis, but it would be really complicated to implement that at this late stage.
I’ll probably make a decision and then try and sort out my documentation before going any further. I’d like to be able to see the language all laid out in front of me, as well as be able to give it to some people to play with. Only when other programmers are using it will the bugs and problems show themselves.
One thing is clear, I am getting more comfortable working in the language. I’m remembering not to put semi-colons at the end of lines for a start.
Commenting
The first step was commenting out every relevant line of code. The second step was to work through it all, section by section, re-writing it all, testing each individual part until it all worked in harmony.
And work it did.
Although I had to repeat that second step about six times until it did. I’ve now got code that draws as many windows as you want, z-order’s them correctly, let’s you move them about the screen, and can properly contain controls. I don’t know whether or not you need to be able to close them, minimise them, resize them etc, so I can’t decide if I need to implement that or not. On one hand, I’m tempted to do it for the coolness factor, on the other hand I’d rather just get the game up and running as quickly as possible.
Whatever I do decide, the sense of achievement that the basics are working is fabulous.
Regardless
It took a while, but I did manage to motivate myself tonight to work more on the game code. I realised that what I had was fundamentally broken, and that treating windows and the controls within those windows as seperate object types was incredibly stupid when they share so many of the same attributes. I always have a problem breaking code that’s already producing results, even if breaking it is necessary to make it work better, but I went ahead tonight and did it anyway, re-writing a good chunk of what I had already.
What I’m left with is something which still isn’t 100% right, being broken in areas that weren’t broken before and fixed in areas that were. It’s all very confusing, but I’m choosing sleep over code, and heading off to bed regardless.
I’ll tackle it again tomorrow night, where I might have to resort to a pen and some pieces of paper so I can simulate exactly what the code is doing.
Elements
Working more on "Our Game" tonight, getting the console interface up and running. This is so you can issue commands like loadmap, savemap, loadtiles etc so that you can actually use it as an editor. Basically trying to imitate a UNIX command line. Having real issues with the zorder of controls on the screen and making sure that when you click somewhere it does actually select the window or item that is under the cursor. This was working fine before when I just had windows on the screen, but now that those windows contain elements as well… things have all gone a bit screwy.
Will keep hacking at it, would certainly hate to have to rethink my whole window model after getting it all working so well initially.
I won’t bother posting another screenshot, it doesn’t look that much different from the last one. Give me a few more days.
I also installed a new 250GB hard disk in my video server (WOPR) which now stands at 630GB. That’s the last disk I can possibly fit in there, so once this one is full I need to start getting creative. This allowed me to start copying over some of the MAME games I had downloaded, allowing me to play them on the TV with an Xbox Joypad (I bought a little USB adapter for them a while back). Of course all I ended up playing was Galaga, which I am slowly becoming addicted to.
Lies
Lies, damn lies, and… more lies.
foreach
Since I still can’t create a useable interface for the VCE (well, I can create a useable one, I just can’t create one that’ll load in an instant), can’t decide how the documentation should be laid out and can’t decide how components, code, templates and configuration all link together, today I went back to basics and actually worked on the Bearscript language feature set instead.
I never really sat down at the beginning and wrote a definitive list of what the inbuilt keywords should be. I always had a rough list of the objects that would be needed (for handling images, files, database etc), but never the basic language structure. Instead I’ve been looking at the kind of things I write in Perl and the commands I use to achieve them, then creating a Bearscript equivelant. Hopefully making it simpler in the process. Today I realised I was lacking the foreach command and in the process of adding that also fixed up my arrays and keyarrays (or hashrefs for you Perl folks), my text handling, string interpolation and email control.
This means that it is now possible to execute code like the following…
# Create email object
mymail = new email()
# Set the properties of the object
mymail.to = “richard@square8.com”
mymail.subject = “My Email Subject”
mymail.body = “This is just a small message to say hello”
# And execute the send method
mymail.send()
Or some array handling…
# Create an array object and fill it up
testarray = new array(”item 1″, “item 2″, “item 3″)
# Loop through all the items within the array and show them
foreach item in testarray
output item & “\n”
next
Or outputting every line in a file…
# Create a file handler object
file = new file()
# Go through each line within the file
# The filetoarray method of the file object loads the file and
# converts each line of it to an array item
foreach line in file.filetoarray(”/web/bear/run.pl”)
output line & “\n”
next
I think next I’m going to try and finalise the database interface before making a final decision on the component structure. But even without them, you can write some pretty significant code in Bearscript now.
If only I could get used to not putting ; at the end of lines.
Demotivational
After so many years of writing web applications in Perl, turning my hand to game programming is proving incredibly difficult. I used to do games in AMOS on the Amiga many years ago, so have done this style of coding before, but returning to it now in Blitz Basic I find that my brain just doesn’t work like it used to. I’m used to writing code that starts at the top, runs to the bottom, and finishes. Now I have to think about code that runs continuously, always drawing the correct items on the screen at the same time as taking whatever input is necessary. So I just end up writing a spaghetti mess.
The other thing that makes it so difficult is how long it takes to get anything working. I’m used to being able to crank things out in Perl so quickly that switching to a language I don’t know too well coupled with how much more complex game code is means that there’s not the instant visual feedback I’m used to. I’m looking at weeks of work just to see anything significant on the screen, instead of hours for Perl stuff, and that’s very demotivational (is that even a word?).
On the other hand, the end result should be much more satisfying. Not only will I have created an original game, but I’ll have completed a much harder programming challenge.
I just have to find other ways to motivate myself.
Disappointment
I have not the words.
Rules
Rules for life I’ve learned over the past year…
1. If you think something is going to make you happy, it won’t happen.
2. The more you want something to happen, the less likely it will.
3. If you have to wait to see if something is going to happen, nothing ever will.
4. Expect nothing, because that’s what you’ll get.