Thursday, January 12, 2012

Counting the Images in a Sprite File

This is it, my friends.
These are these obscene lengths we go to to completely screw with the engine in ways it was probably never meant to be used, to get some pointless little piece of information out of it.

Dear, dear C2E developers. Why did it not occur to you to include a command to list how many images are in a sprite file? Even a modification of SNAX to check if a particular pose existed would have been lovely. No, instead it comes to this, scripts in which ERRORS ARE VOLUNTARILY THROWN to find out something so, so simple.

Le sigh.

So I'm sure this breaks every Best Practice for coding... but the basic idea behind the code is this.

We create an agent, that, upon being mesg wrt+'d a sprite filename, creates a test agent with that sprite file.
It then turns autokill on to avoid the inevitable errors, and then prompts the text agent to increase its pose.
After each pose increase, it checks to see if it's still there (and hasn't autokilled itself).
It keeps count of the pose increases and, when the agent does error and autokill, it outputs the last post increase that worked, and thus the last image in the file.

I'm ...fairly certain autokill is not meant to be used this way. And I'm not sure what the consequences might be of running scripts like this constantly, ones that create and hide errors. I'm not a fan of using autokill to cover up mistakes or problems that could be solved by better coding. But I think this is the only choice in this case.

What would you guys call this? Clever error handling, or a dirty trick?

View the cosfile here, and make whatever use of it that you wish. Edit, copy, re-purpose, whatever.

Injecting the code itself will do nothing at first-- here is how you use it:

If you're just testing it from the command line:
rtar 1 1 22932 mesg wrt+ targ 1000 "[FILENAME]" "_hand" 0
Will make the hand-bubble output the number of images.

If an agent is prompting it, you can do it one of two ways:

rtar 1 1 22932 mesg wrt+ targ 1000 "[FILENAME]" "[STRING]" 0
This will have the agent set the [string] as a NAME variable in the FROM agent as an integer containing the count. So if your string is "spritecount" then the agent will setv NAME "spritecount" to equal the number of images so the agent can access the number later.

rtar 1 1 22932 mesg wrt+ targ 1000 "[FILENAME]" [INTEGER] 0
This will tell the agent to MSG WRT+ the script of the given [integer] of FROM agent, with _p1_ being the results of the image count.

Since the image-counting agent takes several ticks to count through, the output won't be available for use immediately, hence the second option.

A couple of thoughts on this whole thing:

The notion of creating a dummy/test agent is something I came across while writing the Garden Box. As I was pretty much re-writing the agent injector, I referenced it a lot and found that the injector has a similar mechanism-- it actually creates a "dummy" injector that injects the agent, and if it throws any errors, collects and displays them in the injector window. This way the agent injector doesn't autokill itself. Granted, the agent injector doesn't turn autokill on and try to create errors.

I'm sure this system, dirty as it is, could be applied to discover things other than counting images, I'm just not sure what.

And intentional error throwing aside, the actual way this agent works is something I've been wanting to try for a while-- you mesg wrt+ something to it and it returns a variable-- so the agents sort of talk to each other. I think maybe systems like this could be used to implement really primitive functions. Unfortunately it's not something that can be done instantly, but it might have some use down the line.

I sometimes think I'm completely losing my mind in this stuff. I question enough on a daily basis why exactly I continue to dig so deeply into a coding language that maybe a hundred or so people in the world, tops, will ever gain any benefit from. And now in cases like this, I'm not even coding for the sake of making the game better; I'm coding for the joy of solving problems that no one even needs solved.

I should get back to working on the garden box. Actually the garden box itself has been done for weeks, it's just that I was writing the patch plant scripts and got sick of coding dialogue boxes and went off to find a way to make that easier and started poking in PHP and I don't even know when I decided to try and find a way to count sprite files. But maybe I'll get back on track now. Kind of. I still need to develop a decent dialogue box system; that's going to take time.

I still can't believe there's no command for counting images. Knowing me though, there probably is, and I'm just blind to it, and went through all this agony to make myself look ridiculous.

It was fun agony, though.


  1. "It was fun agony". Words I'm sure only a programmer truly understands...

    1. Gah, isn't it the truth though! At least I am not alone!

  2. "I sometimes think I'm completely losing my mind in this stuff."
    Spoken like a true Shee.

    1. Haha, I'm not sure whether to take that as a compliment or a warning of impending insanity :P