I was trying to make a video showcasing the progress on the Garden Box, only to discover than my microphone has finally died, and I can't explain it as well with text-captions. So in the meantime, have something cute:
A Creatures blog about everything from raising norns traditionally to tinkering with their brains to changing the world they live in.
Monday, January 23, 2012
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.
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.
Wednesday, January 11, 2012
CAOS Notes: WOLF
From the CAOS documentation:
WOLF (integer) kanga_mask (integer) eeyore_mask (integer)
Provides various functions to distort space-time and otherwise help with wolfing runs. Set an AND and an EOR mask, to control the following bits:
1 - Display rendering. Turning it off speeds the game up.
2 - Fastest ticks. The game usually runs at a maximum of 20 frames per second. If this is set, it instead runs as fast as it can.
4 - Refresh display at end of tick. If set, then the display is updated at the end of the tick, and the flag is cleared.
8 - Autokill. If set, agents which generate run errors are automatically killed, as the command line option.
This can be a pretty confusing command to understand. It seems, just by glancing at the bits that this would work something like ATTR, wherein, say, if you wanted to have both autokill and fast ticks on, it would total to 10. But knowing that, where do these "kanga" and "eeyore" masks come in?
It's a little complex, but once you get the hang of how this works, it's really pretty neat. In fact, I kind of wish ATTR and BHVR worked this way-- you could accomplish more in fewer lines of code.
The thing about WOLF is that it's an integer, not a command. You can't set WOLF by just entering WOLF 8 or whatever, like you would with ATTR and BHVR. You have to actually set it as though it were a variable to alter it.
To find out what your game's WOLF currently is, open the command line and enter outv wolf 15 0. Why 15 and 0? We'll get to that.
Depending on your autokill status, your game probably returned 1 or 9. 1 being on for display rendering, and 8 being added to that if your autokill is on.
So here's a bit of mental review; WOLF only has four traits to worry about, so it's easy to take an output value and do the math in your head. So if your WOLF returned 15, what traits would be "on"? What if it returned 12? 7? 0? You'll have to have a decent grasp on this to understand how WOLF works.
15 would mean, yes, that all four traits, Display (1), Fast Ticks (+2), Refresh (+4), and Autokill (+8) are on. 12 would mean only Refresh (4) and Autokill (+8) are on, and 7 means Display (1), Fast Ticks (+2), and Refresh (+4) are on. 0 implies that no traits are on at all. This might be elementary to you by now from working with similar constructs in ATTR and BHVR.
Bear with me-- let's repeat the exercise looking for different answers. If WOLF returned 15, what traits would be "off"? What of 12, 7, or 0?
I'm sure you're clever enough to figure out the answers are the opposite of the above-- if a trait isn't on, it's obviously off. So 15 would have no "off" traits, 12 would have Display and Fast Ticks off, 7 means Autokill is off, and 0 means that all four traits are off.
I hope this exercises aren't totally fruitless-- the point that when you glance at a WOLF number, you need to think of it in terms of both what traits are off, as well on.
So now that your WOLF deciphering muscles are working, let's dive into the hard stuff: The masks.
These four "rules" here are all you need to know to decipher what your AND ("Kanga") and OR ("Eeyore") masks need to be:
1. If a trait is off in the AND mask and on in the OR mask, the resulting trait will be on.
2. If a trait is off in the AND mask and off in the OR mask, the resulting trait will be off.
3. If a trait is on in the AND mask and off in the OR mask, the resulting trait will be the same.
4. If a trait is on in the AND mask and on in the OR mask, the resulting trait will be the opposite.
Using these masks, then, you will essentially be able to, in one line, set your wolf controls any way you want them, even taking into account what they already are.
Let's go back to the line we used: outv wolf 15 0.
In this case, 15 is the AND mask, and 0 is the OR mask. That means that all the traits are on in the AND mask and off in the OR mask, which, according to rule 3, the traits will remain the same, unchanged, and the output will be the current WOLF value.
But let's say we wanted to turn all the traits on. To turn a train on, we have to follow rule 1, and make sure all the traits are off in the AND mask (making it 0) and on in the OR mask (making it 15). So we would outv wolf 0 15, which should return 15 and, depending on your computer, may make your world look like it's in super-speed mode (due to both fast ticks and rendering being on).
Before I go any further I need to address something odd before all sorts of questions come up. WOLF is a little bit odd in that 1 (Display) and 4 (Refresh) cannot be on at the same time. If the game is displaying rendering, there's obviously then no reason to refresh the display as it's already being refreshed. So if you set WOLF to 15, 5, 7, or any value that sets both Display and Refresh to on, the engine will automatically turn refresh back off after setting it. So even if you use outv wolf 0 15 to set the WOLF to 15, if you enter outv wolf 15 0 to check it, you'll get back 11, since refresh has been turned off. As far as I can tell, Display always overrides Refresh, not vice versa.
Anyway, now that that's out of the way.
Quiz time again: What would outv wolf 0 0 do?
Since all traits are off in both AND and OR masks, we would look to rule 2, which tells us all the traits will be off. Thus the above command would set your WOLF to 0. It will also sort of freeze up your game, since Display is off-- opening and closing Wolf Control will reset it to normal.
But let's get down to practical information now-- if you're coding something interesting, chances are you're not looking to turn everything on and off at once. Let's try a line that toggles fast ticks on and off. This will really only be apparent on machines that are fast enough to benefit from fast ticks with the display still running-- you might want to try it in a clean and undocked DS world if you're not seeing the difference.
outv wolf 15 2
Enter that once and watch your game spaz out. Enter it again and watch it return to normal.
Can you decipher why this works? This table might help explain exactly what's going on in this command:
So setting up the masks this way allows for all the other traits to stay the way they are, while fast ticks is set to toggle (turn off if it was already on, turn on if it was off). In fact, you could use this table as a tool to work backwards from to find the masks for virtually anything you want to accomplish.
Say you want to make a switch that turns Display on, toggles Fast Ticks, turns Refresh off, and leaves Autokill the way it is. You would start with a table like this, putting in your own desired results.
Next you look at the rules that would give you those desired results. I'm going to paste them again so you don't have to scroll all the way back up:
1. If a trait is off in the AND mask and on in the OR mask, the resulting trait will be on.
2. If a trait is off in the AND mask and off in the OR mask, the resulting trait will be off.
3. If a trait is on in the AND mask and off in the OR mask, the resulting trait will be the same.
4. If a trait is on in the AND mask and on in the OR mask, the resulting trait will be the opposite.
So if you want Display to be on, you'll have to find the rule that gives you the on result. Since that is rule one, you'll want to follow it, setting the trait off in the AND mask and on in the OR mask:
Now just fill in the rest of the chart, following the rules reversely.
To get opposite fast ticks, follow rule 4 and set both masks to on
To turn refresh off, follow rule 2 and set both masks to off.
Finally, to keep autokill the same, follow rule 3 to set AND to on and OR to off.
In the end, you should have something like this:
What does that leave? Just adding up the values of your on traits. Fast ticks (2) and Autokill (8) are on in your AND mask, totally to 10, while Display (1) and Fast Ticks (2) are on in your OR mask, totaling 3.
And that means, to set these values via the command line, outv wolf 10 3.
And that, my friends, is how you spend 14 hours using WOLF to set some settings you will probably never use.
You're probably going to pull your eyes out of your head and cry when I reveal the absolutely trivial purpose I have behind working all this out.
TL;DR:
I don't blame you. Screw it, I'll just write up a WOLF calculator someday.
WOLF (integer) kanga_mask (integer) eeyore_mask (integer)
Provides various functions to distort space-time and otherwise help with wolfing runs. Set an AND and an EOR mask, to control the following bits:
1 - Display rendering. Turning it off speeds the game up.
2 - Fastest ticks. The game usually runs at a maximum of 20 frames per second. If this is set, it instead runs as fast as it can.
4 - Refresh display at end of tick. If set, then the display is updated at the end of the tick, and the flag is cleared.
8 - Autokill. If set, agents which generate run errors are automatically killed, as the command line option.
This can be a pretty confusing command to understand. It seems, just by glancing at the bits that this would work something like ATTR, wherein, say, if you wanted to have both autokill and fast ticks on, it would total to 10. But knowing that, where do these "kanga" and "eeyore" masks come in?
It's a little complex, but once you get the hang of how this works, it's really pretty neat. In fact, I kind of wish ATTR and BHVR worked this way-- you could accomplish more in fewer lines of code.
The thing about WOLF is that it's an integer, not a command. You can't set WOLF by just entering WOLF 8 or whatever, like you would with ATTR and BHVR. You have to actually set it as though it were a variable to alter it.
To find out what your game's WOLF currently is, open the command line and enter outv wolf 15 0. Why 15 and 0? We'll get to that.
Depending on your autokill status, your game probably returned 1 or 9. 1 being on for display rendering, and 8 being added to that if your autokill is on.
So here's a bit of mental review; WOLF only has four traits to worry about, so it's easy to take an output value and do the math in your head. So if your WOLF returned 15, what traits would be "on"? What if it returned 12? 7? 0? You'll have to have a decent grasp on this to understand how WOLF works.
15 would mean, yes, that all four traits, Display (1), Fast Ticks (+2), Refresh (+4), and Autokill (+8) are on. 12 would mean only Refresh (4) and Autokill (+8) are on, and 7 means Display (1), Fast Ticks (+2), and Refresh (+4) are on. 0 implies that no traits are on at all. This might be elementary to you by now from working with similar constructs in ATTR and BHVR.
Bear with me-- let's repeat the exercise looking for different answers. If WOLF returned 15, what traits would be "off"? What of 12, 7, or 0?
I'm sure you're clever enough to figure out the answers are the opposite of the above-- if a trait isn't on, it's obviously off. So 15 would have no "off" traits, 12 would have Display and Fast Ticks off, 7 means Autokill is off, and 0 means that all four traits are off.
I hope this exercises aren't totally fruitless-- the point that when you glance at a WOLF number, you need to think of it in terms of both what traits are off, as well on.
So now that your WOLF deciphering muscles are working, let's dive into the hard stuff: The masks.
These four "rules" here are all you need to know to decipher what your AND ("Kanga") and OR ("Eeyore") masks need to be:
1. If a trait is off in the AND mask and on in the OR mask, the resulting trait will be on.
2. If a trait is off in the AND mask and off in the OR mask, the resulting trait will be off.
3. If a trait is on in the AND mask and off in the OR mask, the resulting trait will be the same.
4. If a trait is on in the AND mask and on in the OR mask, the resulting trait will be the opposite.
Using these masks, then, you will essentially be able to, in one line, set your wolf controls any way you want them, even taking into account what they already are.
Let's go back to the line we used: outv wolf 15 0.
In this case, 15 is the AND mask, and 0 is the OR mask. That means that all the traits are on in the AND mask and off in the OR mask, which, according to rule 3, the traits will remain the same, unchanged, and the output will be the current WOLF value.
But let's say we wanted to turn all the traits on. To turn a train on, we have to follow rule 1, and make sure all the traits are off in the AND mask (making it 0) and on in the OR mask (making it 15). So we would outv wolf 0 15, which should return 15 and, depending on your computer, may make your world look like it's in super-speed mode (due to both fast ticks and rendering being on).
Before I go any further I need to address something odd before all sorts of questions come up. WOLF is a little bit odd in that 1 (Display) and 4 (Refresh) cannot be on at the same time. If the game is displaying rendering, there's obviously then no reason to refresh the display as it's already being refreshed. So if you set WOLF to 15, 5, 7, or any value that sets both Display and Refresh to on, the engine will automatically turn refresh back off after setting it. So even if you use outv wolf 0 15 to set the WOLF to 15, if you enter outv wolf 15 0 to check it, you'll get back 11, since refresh has been turned off. As far as I can tell, Display always overrides Refresh, not vice versa.
Anyway, now that that's out of the way.
Quiz time again: What would outv wolf 0 0 do?
Since all traits are off in both AND and OR masks, we would look to rule 2, which tells us all the traits will be off. Thus the above command would set your WOLF to 0. It will also sort of freeze up your game, since Display is off-- opening and closing Wolf Control will reset it to normal.
But let's get down to practical information now-- if you're coding something interesting, chances are you're not looking to turn everything on and off at once. Let's try a line that toggles fast ticks on and off. This will really only be apparent on machines that are fast enough to benefit from fast ticks with the display still running-- you might want to try it in a clean and undocked DS world if you're not seeing the difference.
outv wolf 15 2
Enter that once and watch your game spaz out. Enter it again and watch it return to normal.
Can you decipher why this works? This table might help explain exactly what's going on in this command:
AND | OR | Rule | Result | |
Value | 15 | 2 | * | * |
1 - Display | ON | OFF | 3 | Same |
2 - Fast Ticks | ON | ON | 4 | Opposite |
4 - Refresh | ON | OFF | 3 | Same |
8 - Autokill | ON | OFF | 3 | Same |
So setting up the masks this way allows for all the other traits to stay the way they are, while fast ticks is set to toggle (turn off if it was already on, turn on if it was off). In fact, you could use this table as a tool to work backwards from to find the masks for virtually anything you want to accomplish.
Say you want to make a switch that turns Display on, toggles Fast Ticks, turns Refresh off, and leaves Autokill the way it is. You would start with a table like this, putting in your own desired results.
AND | OR | Rule | Result | |
Value | ? | ? | * | * |
1 - Display | ? | ? | ? | On |
2 - Fast Ticks | ? | ? | ? | Opposite |
4 - Refresh | ? | ? | ? | Off |
8 - Autokill | ? | ? | ? | Same |
Next you look at the rules that would give you those desired results. I'm going to paste them again so you don't have to scroll all the way back up:
1. If a trait is off in the AND mask and on in the OR mask, the resulting trait will be on.
2. If a trait is off in the AND mask and off in the OR mask, the resulting trait will be off.
3. If a trait is on in the AND mask and off in the OR mask, the resulting trait will be the same.
4. If a trait is on in the AND mask and on in the OR mask, the resulting trait will be the opposite.
So if you want Display to be on, you'll have to find the rule that gives you the on result. Since that is rule one, you'll want to follow it, setting the trait off in the AND mask and on in the OR mask:
AND | OR | Rule | Result | |
Value | ? | ? | * | * |
1 - Display | OFF | ON | 1 | On |
2 - Fast Ticks | ? | ? | ? | Opposite |
4 - Refresh | ? | ? | ? | Off |
8 - Autokill | ? | ? | ? | Same |
Now just fill in the rest of the chart, following the rules reversely.
To get opposite fast ticks, follow rule 4 and set both masks to on
To turn refresh off, follow rule 2 and set both masks to off.
Finally, to keep autokill the same, follow rule 3 to set AND to on and OR to off.
In the end, you should have something like this:
AND | OR | Rule | Result | |
Value | ? | ? | * | * |
1 - Display | OFF | ON | 1 | On |
2 - Fast Ticks | ON | ON | 4 | Opposite |
4 - Refresh | OFF | OFF | 2 | Off |
8 - Autokill | ON | OFF | 3 | Same |
What does that leave? Just adding up the values of your on traits. Fast ticks (2) and Autokill (8) are on in your AND mask, totally to 10, while Display (1) and Fast Ticks (2) are on in your OR mask, totaling 3.
AND | OR | Rule | Result | |
Value | 10 | 3 | * | * |
1 - Display | OFF | ON | 1 | On |
2 - Fast Ticks | ON | ON | 4 | Opposite |
4 - Refresh | OFF | OFF | 2 | Off |
8 - Autokill | ON | OFF | 3 | Same |
And that means, to set these values via the command line, outv wolf 10 3.
And that, my friends, is how you spend 14 hours using WOLF to set some settings you will probably never use.
You're probably going to pull your eyes out of your head and cry when I reveal the absolutely trivial purpose I have behind working all this out.
TL;DR:
I don't blame you. Screw it, I'll just write up a WOLF calculator someday.
CAOS Notes: ORRV
Let's say you want to make everything in your world carryable by the hand.
This is actually a terrible idea and a great way to screw up your world, but let's throw all that to the wind and have ourselves some chaos.
enum 0 0 0
setv va00 attr
orrv va00 2
attr va00
next
Yes, 0 0 0. If this kills your game you may want to filter it a bit.
ORRV is another weird little command. If you ORRV an ATTR or BHVR value, it will, similar to ANDV, spit out a number that will tell you if the value you're checking is set or not. Only if the value is set, instead of spitting out the value you're checking, it'll spit out your original attr/bhvr.
So in our last lesson:
setv va00 bhvr
andv va00 16
If va00 = 16, the eatable bhvr is set.
You can do the same thing with ORRV:
setv va00 bhvr
orrv va00 16
But va00 will equal bhvr, not 16, if that bhvr is set. (doif va00 = bhvr...)
There's always a thousand ways to code the same thing, so just do whatever you want.
ORRV, however, has this neat little side effect, you see. If the value you're checking for is not set, ORRV will return the ATTR or BHVR value that your agent would have if it was it set.
So if you want to set an agent as invisible, suffering physics, or whatever, ORRV it, and then just ATTR the value. If it's already set, it'll have no effect, and it if it's not, it will be.
Of course, you could accomplish the same with ANDV, it would just take more lines than necessary:
enum 0 0 0
setv va00 attr
andv va00 2
doif va00 ne 2
setv va00 attr
addv va00 2
attr va00
endi
next
ORRV is just easier in this case.
Avoid using this to set BHVR values, since those, unlike ATTR values, actually need certain scripts to run and will throw errors if you don't have them. Also remember that if you set an agent to suffer physics, you'll actually have to give it some physics for it to mean anything (ACCG, ELAS, FRIC, etc).
So ORRV is nice for setting attributes an agent doesn't already have, but if you wanted to, say, make all your agents unmovable (to restrain yourself from interfering in a wolfling run, maybe), you'd still have to subtract the value manually:
enum 0 0 0
setv va00 attr
orrv va00 2
doif va00 eq attr
subv va00 2
attr va00
endi
next
Anyway, hopefully by now you have the hang of using ANDV and ORRV for your ATTR/BHVR checking and changing needs. I'm still grasping it myself, so if you're a wiser sort and see anything that I'm missing, do share the knowledge for the benefit of all!
This is actually a terrible idea and a great way to screw up your world, but let's throw all that to the wind and have ourselves some chaos.
enum 0 0 0
setv va00 attr
orrv va00 2
attr va00
next
Yes, 0 0 0. If this kills your game you may want to filter it a bit.
ORRV is another weird little command. If you ORRV an ATTR or BHVR value, it will, similar to ANDV, spit out a number that will tell you if the value you're checking is set or not. Only if the value is set, instead of spitting out the value you're checking, it'll spit out your original attr/bhvr.
So in our last lesson:
setv va00 bhvr
andv va00 16
If va00 = 16, the eatable bhvr is set.
You can do the same thing with ORRV:
setv va00 bhvr
orrv va00 16
But va00 will equal bhvr, not 16, if that bhvr is set. (doif va00 = bhvr...)
There's always a thousand ways to code the same thing, so just do whatever you want.
ORRV, however, has this neat little side effect, you see. If the value you're checking for is not set, ORRV will return the ATTR or BHVR value that your agent would have if it was it set.
So if you want to set an agent as invisible, suffering physics, or whatever, ORRV it, and then just ATTR the value. If it's already set, it'll have no effect, and it if it's not, it will be.
Of course, you could accomplish the same with ANDV, it would just take more lines than necessary:
enum 0 0 0
setv va00 attr
andv va00 2
doif va00 ne 2
setv va00 attr
addv va00 2
attr va00
endi
next
ORRV is just easier in this case.
Avoid using this to set BHVR values, since those, unlike ATTR values, actually need certain scripts to run and will throw errors if you don't have them. Also remember that if you set an agent to suffer physics, you'll actually have to give it some physics for it to mean anything (ACCG, ELAS, FRIC, etc).
So ORRV is nice for setting attributes an agent doesn't already have, but if you wanted to, say, make all your agents unmovable (to restrain yourself from interfering in a wolfling run, maybe), you'd still have to subtract the value manually:
enum 0 0 0
setv va00 attr
orrv va00 2
doif va00 eq attr
subv va00 2
attr va00
endi
next
Anyway, hopefully by now you have the hang of using ANDV and ORRV for your ATTR/BHVR checking and changing needs. I'm still grasping it myself, so if you're a wiser sort and see anything that I'm missing, do share the knowledge for the benefit of all!
CAOS Notes: Can I eat this?
Ever want to use CAOS to check if an object is edible? Invisible? Pickup-able by the hand?
Deciphering ATTR and BHVR values at a glace isn't the easiest thing in the world, and it's not exactly glaringly obvious how one would do so with CAOS, either. This is just a really simple script that teleports everything in the world that is edible by creatures to the hand, to demo how you might go about identifying BHVR or ATTR values in an agent.
enum 2 0 0
setv va00 bhvr
andv va00 16
doif va00 = 16 and movs = 0
mvsf mopx mopy
velo 0 0
endi
next
(Yes, this enums through everything in family 2. In big worlds, on slower machines, you might not want to run this script as it may lag you to oblivion and back. Try a clean DS-standalone world if you're having problems.)
It's really difficult to explain exactly how ANDV works if you have no background knowledge of bitwise operators. Heck, I confuse myself with it. But what you really need to know is this:
If you ANDV an agent's ATTR/BHVR value with the ATTR/BHVR value you're checking for, it will return that same value if it is valid.
Say you want to find out if an agent is set to Suffer Physics (ATTR number 128), you would set the ATTR in a variable and ANDV it 128. If it returns 128, the agent does indeed suffer physics. If it returns anything else, it does not.
So in this above example you can see that we've taken the BHVR number that declares the creature can eat said agent, 16, and ANDV'd it to the BHVR. If it returns 16 (and movs = 0, to stop it from trying to move items in vehicles and throwing errors), it is indeed edible, and thus is moved.
If you run this script, assuming your pointer is in a valid spot, all the edible objects in the world should come spewing forth from your fingertip. You'll notice this includes edible critters, including fish from your ponds and pests. Go on and try it!
You did try it, right?
You've probably noticed then, depending on what you've got in your world, that some of the agents weren't the sort of thing the game intended on having moved. Apples and blossoms may hang in midair, as well as other fruits that had been growing on plants. As an exercise, you might try altering the script to check for physics and collisions as well,
Here's a hint-- you can add the values together that you want to check for. For example, if you wanted to check if a creature could push (BHVR 1) and hit (BHVR 8) an agent, you can add those two and simply ANDV the BHVR 9. If it returns 9, both conditions are true.
I know this is supposed to be a tutorial, but I am having way too much fun spewing food and critters all over the place, so I will have to come back to this later. I am sure you more mature developers out there can actually find something useful to do with these commands.
Deciphering ATTR and BHVR values at a glace isn't the easiest thing in the world, and it's not exactly glaringly obvious how one would do so with CAOS, either. This is just a really simple script that teleports everything in the world that is edible by creatures to the hand, to demo how you might go about identifying BHVR or ATTR values in an agent.
enum 2 0 0
setv va00 bhvr
andv va00 16
doif va00 = 16 and movs = 0
mvsf mopx mopy
velo 0 0
endi
next
(Yes, this enums through everything in family 2. In big worlds, on slower machines, you might not want to run this script as it may lag you to oblivion and back. Try a clean DS-standalone world if you're having problems.)
It's really difficult to explain exactly how ANDV works if you have no background knowledge of bitwise operators. Heck, I confuse myself with it. But what you really need to know is this:
If you ANDV an agent's ATTR/BHVR value with the ATTR/BHVR value you're checking for, it will return that same value if it is valid.
Say you want to find out if an agent is set to Suffer Physics (ATTR number 128), you would set the ATTR in a variable and ANDV it 128. If it returns 128, the agent does indeed suffer physics. If it returns anything else, it does not.
So in this above example you can see that we've taken the BHVR number that declares the creature can eat said agent, 16, and ANDV'd it to the BHVR. If it returns 16 (and movs = 0, to stop it from trying to move items in vehicles and throwing errors), it is indeed edible, and thus is moved.
If you run this script, assuming your pointer is in a valid spot, all the edible objects in the world should come spewing forth from your fingertip. You'll notice this includes edible critters, including fish from your ponds and pests. Go on and try it!
You did try it, right?
You've probably noticed then, depending on what you've got in your world, that some of the agents weren't the sort of thing the game intended on having moved. Apples and blossoms may hang in midair, as well as other fruits that had been growing on plants. As an exercise, you might try altering the script to check for physics and collisions as well,
Here's a hint-- you can add the values together that you want to check for. For example, if you wanted to check if a creature could push (BHVR 1) and hit (BHVR 8) an agent, you can add those two and simply ANDV the BHVR 9. If it returns 9, both conditions are true.
I know this is supposed to be a tutorial, but I am having way too much fun spewing food and critters all over the place, so I will have to come back to this later. I am sure you more mature developers out there can actually find something useful to do with these commands.
Monday, January 9, 2012
PHP, and other ways to enhance Creatures
I’ve been cheating a bit on CAOS, you see. I’ve decided to branch out a bit and dabble in some other programming languages, starting with PHP. I started by writing up some simple ATTR/BHVR calculators; if you’re a developer, you might find these useful. But I’ve been thinking a lot about other ways programming languages besides CAOS can be used to enhance gameplay and benefit our tiny community as a whole.
Of course, other programming languages have been aiding the CC for a long time. Web-based programming is what brings us wonderful tools like LiveGMS and The Creature Repository, not to mention the Creatures Wiki and all our forums and blogs. And it's hard to even start when you get into non-web applications: all our 3rd party sprite viewers, gene editors, and direct game tools like DevThing... why, the community simply would not be the same without these tools.
I decided to start with PHP because web-based programming seems to be the way of the future. My first inclination, as told by my first calculators, is to use PHP as an aid in writing CAOS.
Now, it wouldn't be too impossible to write, say, a code generator in which you input a few variables like classifiers, image file names, and so on, and it spits out the cosfile for a basic food/toy agent. But I just really don't see that benefiting the community much, especially since, in my opinion, I believe we as developers ought to be focusing on additions to the game that mix things up and change the way we play; not just creating more of the same thing with different sprites.
But on the other hand, it might be a good starting point for new developers-- they might excitedly generate a Creatures version of their favorite toy and then seek to learn out to alter it to make it more complex, which could be a lot less intimidating than writing code from scratch. Something else to consider is the occasional newbie who is still enchanted by vanilla gameplay and would really enjoy a simple way to create their own food and toys on a whim.
But if I'm going to make code generators, I'm more inclined to generate Magic Words templates or code for dialogue boxes (I hate, hate coding dialogue boxes; finding an easier way is actually very high priority for me)
Something else that's been brought up is the notion of a web-based version of EasyPRAY. Personally, I think that utilizing something like CAOS2PRAY would remain easier, since the "blanks" you fill in would be about the same, only you'd have to go through the extra steps of opening your browser and downloading the generated prayfile. But it's still something to consider, particularly since agents for the Garden Box I've been working on actually use their own chunk type-- something neither EasyPRAY nor CAOS2PRAY supports. I also might be able to code a way to search the cosfile for potential dependencies, which could take some work off the developer's hands.
So the potential of using PHP to develop CAOS aids is certainly there, but what about other aspects of development? Something I was tossing in my head long before I picked up PHP was the idea of a site that focused on collaborative community projects, with a variety of features.
The first aspect would be a sort of developers' database, wherein developers (anyone registered on the site) would create a profile containing contact information, information about what they like to develop, their availability, and their skillsets, be that CAOS, spriting, 3D modeling, gene editing, concept sketching, as well as other programming languages and really, any skill that might be useful to the community. You could then basically search for a spriter or a coder or whatever you needed, and then contact them to see if they were interested in helping you out.
The second aspect would be a project ideas database, where people could post project proposals and ideas, and other users could vote in favor or against certain ideas. It would then be easy to gauge what ideas were popular and in demand just by glancing at the list. When an idea became popular enough, it would open up to development. A project manager (by default, the user who proposed the idea, but the role could be handed off to someone else if needed, or even shared among multiple people) would then make a task list.
Each task would include the skillset required and a detailed description of what needed to be done. Some tasks would obviously need do only be done once, something like "Spriting: A red and yellow-striped beach ball with animations for bouncing and popping." but it could also be a repeatable task, especially in the early/planning stages, something like "Sketching: Five concepts for undersea creatures, front and side views."
Interested contributors could then search for tasks that were needed by category and apply for them. Some tasks would require approval of the project manager first (to avoid say, someone signing up for something they may not have the skillset for.) Their contributions to various projects would be tracked in their profile.
Another, sort of offshoot feature would be a favor-trading board. This would be for tasks that aren't a part of a larger project; for example, if I was working on a personal project and need a sprite done, or if someone with no scripting experience just wanted an agent that turned norns to statues when they were touched (or something) and couldn't do it for themselves, they could post this on the favor-trading board, and offer something in exchange from their own skillset.
Something like this, while way out of my league at the moment, is still entirely possible for the future. The biggest problem with something this big and well-organized though, is that our community is simply just too small and inactive to fully utilize it. It would be an enormous amount of work for something maybe twenty or so people would really actively use. Still, it's nice to dream sometimes.
What of you guys? Can you think of any web-based programming possibilities that might benefit the community?
Of course, other programming languages have been aiding the CC for a long time. Web-based programming is what brings us wonderful tools like LiveGMS and The Creature Repository, not to mention the Creatures Wiki and all our forums and blogs. And it's hard to even start when you get into non-web applications: all our 3rd party sprite viewers, gene editors, and direct game tools like DevThing... why, the community simply would not be the same without these tools.
I decided to start with PHP because web-based programming seems to be the way of the future. My first inclination, as told by my first calculators, is to use PHP as an aid in writing CAOS.
Now, it wouldn't be too impossible to write, say, a code generator in which you input a few variables like classifiers, image file names, and so on, and it spits out the cosfile for a basic food/toy agent. But I just really don't see that benefiting the community much, especially since, in my opinion, I believe we as developers ought to be focusing on additions to the game that mix things up and change the way we play; not just creating more of the same thing with different sprites.
But on the other hand, it might be a good starting point for new developers-- they might excitedly generate a Creatures version of their favorite toy and then seek to learn out to alter it to make it more complex, which could be a lot less intimidating than writing code from scratch. Something else to consider is the occasional newbie who is still enchanted by vanilla gameplay and would really enjoy a simple way to create their own food and toys on a whim.
But if I'm going to make code generators, I'm more inclined to generate Magic Words templates or code for dialogue boxes (I hate, hate coding dialogue boxes; finding an easier way is actually very high priority for me)
Something else that's been brought up is the notion of a web-based version of EasyPRAY. Personally, I think that utilizing something like CAOS2PRAY would remain easier, since the "blanks" you fill in would be about the same, only you'd have to go through the extra steps of opening your browser and downloading the generated prayfile. But it's still something to consider, particularly since agents for the Garden Box I've been working on actually use their own chunk type-- something neither EasyPRAY nor CAOS2PRAY supports. I also might be able to code a way to search the cosfile for potential dependencies, which could take some work off the developer's hands.
So the potential of using PHP to develop CAOS aids is certainly there, but what about other aspects of development? Something I was tossing in my head long before I picked up PHP was the idea of a site that focused on collaborative community projects, with a variety of features.
The first aspect would be a sort of developers' database, wherein developers (anyone registered on the site) would create a profile containing contact information, information about what they like to develop, their availability, and their skillsets, be that CAOS, spriting, 3D modeling, gene editing, concept sketching, as well as other programming languages and really, any skill that might be useful to the community. You could then basically search for a spriter or a coder or whatever you needed, and then contact them to see if they were interested in helping you out.
The second aspect would be a project ideas database, where people could post project proposals and ideas, and other users could vote in favor or against certain ideas. It would then be easy to gauge what ideas were popular and in demand just by glancing at the list. When an idea became popular enough, it would open up to development. A project manager (by default, the user who proposed the idea, but the role could be handed off to someone else if needed, or even shared among multiple people) would then make a task list.
Each task would include the skillset required and a detailed description of what needed to be done. Some tasks would obviously need do only be done once, something like "Spriting: A red and yellow-striped beach ball with animations for bouncing and popping." but it could also be a repeatable task, especially in the early/planning stages, something like "Sketching: Five concepts for undersea creatures, front and side views."
Interested contributors could then search for tasks that were needed by category and apply for them. Some tasks would require approval of the project manager first (to avoid say, someone signing up for something they may not have the skillset for.) Their contributions to various projects would be tracked in their profile.
Another, sort of offshoot feature would be a favor-trading board. This would be for tasks that aren't a part of a larger project; for example, if I was working on a personal project and need a sprite done, or if someone with no scripting experience just wanted an agent that turned norns to statues when they were touched (or something) and couldn't do it for themselves, they could post this on the favor-trading board, and offer something in exchange from their own skillset.
Something like this, while way out of my league at the moment, is still entirely possible for the future. The biggest problem with something this big and well-organized though, is that our community is simply just too small and inactive to fully utilize it. It would be an enormous amount of work for something maybe twenty or so people would really actively use. Still, it's nice to dream sometimes.
What of you guys? Can you think of any web-based programming possibilities that might benefit the community?
Sunday, January 8, 2012
CAOS2PRAY: An Easier Way
Sometime
last fall, while I was preparing for CCSF, I discovered a little thing
known as CAOS2PRAY. It would not be too much of a stretch to claim that,
were it not for CAOS2PRAY, I may not have gotten around to releasing as
many agents as I did, because I hate, hate hate hate writing prayfiles,
and even easyPRAY was giving me problems.
CAOS2PRAY is basically a method of embedding your PRAY info in your .cos file so you don't have to deal with a separate file (or if you're using easyPRAY, a separate program as well). I really feel that it is a wonderfully simple way to compile agents, but is not very well known or understood; hence this little guide.
All I learned about CAOS2PRAY, I learned from the official documentation here. This tutorial attempts to simplify that manual, but you should refer to it for further information.
CAOS2PRAY was actually developed by RProgrammer as part of Jagent. As such, you need to use Monk to compile your agents for it to be effective. Malkin has already written a simple guide to Monk, so I'll skip those details and jump right into the unknown. Note that this tutorial also assumes you've written a PRAY file before and understand what information is generally required.
Again, CAOS2PRAY is not a program or anything of the sort. It's basically just a syntax you follow to, instead of writing the prayinfo in a separate file, write in the cosfile itself, in a much more simplified fashion.
If you were to decompile my Advanced Muco (or any of my more recent agents), you would notice the top of the cosfile contains text like this:
**CAOS2PRAY
*# Pray-File "advmuco.agents"
*# DS-Name "Advanced Muco"
*# Depend blnk.c16
*# attach advmucoo.c16 advmucohelp.catalogue
*# desc = "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
*# Agent Animation File = "advmucoo.c16"
*# Agent Animation String = "0 1 255"
*# Agent Sprite First Image = 0
*# Agent Animation Gallery = "advmucoo"
*# Web URL = "naturingnurturing.blogspot.com"
*# Web Label = "Naturing :: Nurturing"
This is all I needed to write. Then I just made sure all the inline files were in the same folder, dragged and dropped the cosfile onto monk, and it spit out a complete and packaged agentfile, no prayfile required! It's incredibly easy to write up a "template" like the one above and just copy/paste it at the beginning of your cosfiles, changing the info as needed.
Now, if you're a careful observer, you may have noticed that some lines in the example contain equal signs [=] while others do not. That is because there are two different sorts of lines that Monk understands, commands and tags.
Tags are very simple, so we'll start with them. They're the ones with the equal signs, and they translate directly to the prayfile.
Let's say you write the following lines in CAOS2PRAY:
*# Agent Animation Gallery = "advmucoo"
*# Agent Sprite First Image = 0
*# Banana Cream Pie = "in your face"
*# Number of Pies = 42
This is the same thing as writing the following in a typical prayfile:
"Agent Animation Gallery" "advmucoo"
"Agent Sprite First Image" 0
"Banana Cream Pie" "in your face"
"Number of Pies" 42
Not that you would actually need to define the latter two unless you had a modified agent injector that read those values, but you get the point.
At first glance, it may appear that CAOS2PRAY is more writing than a typical prayfile. But there are shortcuts available, too. You may have noticed in the example, a tag simple labeled "desc"
*# desc = "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
Monk translates this to the following in the prayfile:
"Agent Description" "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
It doesn't matter if you use "desc" or "Agent Description" -- it will be read the same way. Here are the shortcuts that Monk supports:
"anim" -- "Agent Animation String"
"anim file" -- "Agent Animation File"
"desc" -- "Agent Description"
"anim start" OR "anim img" OR "anim image" OR "first image" -- "Agent Sprite First Image"
"bioenergy" "Agent Bioenergy Value"
As you can see, there are shortcuts for a lot of values in the example that I chose to write out instead of using the shortcut. I'm not really sure why I did that. Obviously if you're typing it all out by hand, it would be quicker to use the shortcuts, but in the end it doesn't matter which you use, especially if you're just copy-pasting a template.
Now, the commands. This is where CAOS2PRAY really shines.
Command lines do not contain equal signs, they are simply written as {command} {something}.
The commands are as follows:
Pray-File: This is what the output file will be named. Be sure to include the .agent extension. This is required!
DS-Name: The name of the agent as displayed in the DS agent injector.
C3-Name: The name of the agent as displayed in the C3 agent injector. Only required if your agent is C3-standalone compatible. Remember that your C3 agent name cannot be the same as your DS agent name!
Depend: This specifies dependencies (images, sounds, etc that the agent needs to function) but does not compile them into the agent. These must be separated by spaces and include the file extension. The nice thing about this is that you don't have to define a category like you would when writing a PRAYfile by hand; Monk does this for you. As you can see in my example, I got lazy and didn't include all the dependencies my agent needed. You should probably not follow my example, and instead try to list all the images, sounds, etc that the agent needs, even if they are included with C3/DS, because you never know when someone might accidentally delete half their sounds folder and then spam you with angry messages when they inject your agent and it gets autokilled instead of just throwing a dependency error.
Attach: This specifies dependencies and compiles them into the agent. Monk will throw an error if you don't have these files included in the folder with the cosfile while compiling the agent. Same rules apply as with Depend (must be separated by spaces and include the file extension). You use this for sprites, sounds, catalogue files, etc that are not native to C3/DS. If you list a file in Attach, you do not have to list it in Depend.
Inline: This compiles files into the agent, but will not specify them as a dependencies (unless you also list them in Depend). I'm not really sure why you would use this when you can just use Attach, but it's there, just in case.
Link: Supposedly this allows you to link to other cosfiles you want to include in the agent. I've never used it, though.
As I mentioned earlier, Monk finds your agent's remove script on its own-- you don't need to specify it manually like you would when writing up a prayfile by hand.
Hopefully this guide will help some of you get a grasp on CAOS2PRAY and have an easier time compiling C3/DS agents. If you have any trouble, get confused, or notice any errors in this guide, do let me know. I aim to keep this as understandable and accurate as possible.
CAOS2PRAY is basically a method of embedding your PRAY info in your .cos file so you don't have to deal with a separate file (or if you're using easyPRAY, a separate program as well). I really feel that it is a wonderfully simple way to compile agents, but is not very well known or understood; hence this little guide.
All I learned about CAOS2PRAY, I learned from the official documentation here. This tutorial attempts to simplify that manual, but you should refer to it for further information.
CAOS2PRAY was actually developed by RProgrammer as part of Jagent. As such, you need to use Monk to compile your agents for it to be effective. Malkin has already written a simple guide to Monk, so I'll skip those details and jump right into the unknown. Note that this tutorial also assumes you've written a PRAY file before and understand what information is generally required.
Again, CAOS2PRAY is not a program or anything of the sort. It's basically just a syntax you follow to, instead of writing the prayinfo in a separate file, write in the cosfile itself, in a much more simplified fashion.
If you were to decompile my Advanced Muco (or any of my more recent agents), you would notice the top of the cosfile contains text like this:
**CAOS2PRAY
*# Pray-File "advmuco.agents"
*# DS-Name "Advanced Muco"
*# Depend blnk.c16
*# attach advmucoo.c16 advmucohelp.catalogue
*# desc = "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
*# Agent Animation File = "advmucoo.c16"
*# Agent Animation String = "0 1 255"
*# Agent Sprite First Image = 0
*# Agent Animation Gallery = "advmucoo"
*# Web URL = "naturingnurturing.blogspot.com"
*# Web Label = "Naturing :: Nurturing"
This is all I needed to write. Then I just made sure all the inline files were in the same folder, dragged and dropped the cosfile onto monk, and it spit out a complete and packaged agentfile, no prayfile required! It's incredibly easy to write up a "template" like the one above and just copy/paste it at the beginning of your cosfiles, changing the info as needed.
- To make use of CAOS2PRAY, you need to understand a few things:
- Since you're putting this text directly in the cosfile, you have to start each line with an asterisk [*] to comment it out so it doesn't throw errors when C3/DS tries to read it.
- When compiling with CAOS2PRAY, Monk searches for the hash/pound sign [#]. Thus, you have to start each line that you want Monk to recognize with the asterisk followed by the hash sign [*#]. The only exception is the remove script, which Monk finds on its own.
- It's best to put your CAOS2PRAY info at the top of your cosfile, or at the very least, not at the bottom. Once Monk hits your remove script, it will stop reading further commands, so if your info is at the bottom, under your remove script, Monk won't see it.
Now, if you're a careful observer, you may have noticed that some lines in the example contain equal signs [=] while others do not. That is because there are two different sorts of lines that Monk understands, commands and tags.
Tags are very simple, so we'll start with them. They're the ones with the equal signs, and they translate directly to the prayfile.
Let's say you write the following lines in CAOS2PRAY:
*# Agent Animation Gallery = "advmucoo"
*# Agent Sprite First Image = 0
*# Banana Cream Pie = "in your face"
*# Number of Pies = 42
This is the same thing as writing the following in a typical prayfile:
"Agent Animation Gallery" "advmucoo"
"Agent Sprite First Image" 0
"Banana Cream Pie" "in your face"
"Number of Pies" 42
Not that you would actually need to define the latter two unless you had a modified agent injector that read those values, but you get the point.
At first glance, it may appear that CAOS2PRAY is more writing than a typical prayfile. But there are shortcuts available, too. You may have noticed in the example, a tag simple labeled "desc"
*# desc = "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
Monk translates this to the following in the prayfile:
"Agent Description" "A display next to Muco the Egg Layer that allows you to choose breeds from a list."
It doesn't matter if you use "desc" or "Agent Description" -- it will be read the same way. Here are the shortcuts that Monk supports:
"anim" -- "Agent Animation String"
"anim file" -- "Agent Animation File"
"desc" -- "Agent Description"
"anim start" OR "anim img" OR "anim image" OR "first image" -- "Agent Sprite First Image"
"bioenergy" "Agent Bioenergy Value"
As you can see, there are shortcuts for a lot of values in the example that I chose to write out instead of using the shortcut. I'm not really sure why I did that. Obviously if you're typing it all out by hand, it would be quicker to use the shortcuts, but in the end it doesn't matter which you use, especially if you're just copy-pasting a template.
Now, the commands. This is where CAOS2PRAY really shines.
Command lines do not contain equal signs, they are simply written as {command} {something}.
The commands are as follows:
Pray-File: This is what the output file will be named. Be sure to include the .agent extension. This is required!
DS-Name: The name of the agent as displayed in the DS agent injector.
C3-Name: The name of the agent as displayed in the C3 agent injector. Only required if your agent is C3-standalone compatible. Remember that your C3 agent name cannot be the same as your DS agent name!
Depend: This specifies dependencies (images, sounds, etc that the agent needs to function) but does not compile them into the agent. These must be separated by spaces and include the file extension. The nice thing about this is that you don't have to define a category like you would when writing a PRAYfile by hand; Monk does this for you. As you can see in my example, I got lazy and didn't include all the dependencies my agent needed. You should probably not follow my example, and instead try to list all the images, sounds, etc that the agent needs, even if they are included with C3/DS, because you never know when someone might accidentally delete half their sounds folder and then spam you with angry messages when they inject your agent and it gets autokilled instead of just throwing a dependency error.
Attach: This specifies dependencies and compiles them into the agent. Monk will throw an error if you don't have these files included in the folder with the cosfile while compiling the agent. Same rules apply as with Depend (must be separated by spaces and include the file extension). You use this for sprites, sounds, catalogue files, etc that are not native to C3/DS. If you list a file in Attach, you do not have to list it in Depend.
Inline: This compiles files into the agent, but will not specify them as a dependencies (unless you also list them in Depend). I'm not really sure why you would use this when you can just use Attach, but it's there, just in case.
Link: Supposedly this allows you to link to other cosfiles you want to include in the agent. I've never used it, though.
As I mentioned earlier, Monk finds your agent's remove script on its own-- you don't need to specify it manually like you would when writing up a prayfile by hand.
Hopefully this guide will help some of you get a grasp on CAOS2PRAY and have an easier time compiling C3/DS agents. If you have any trouble, get confused, or notice any errors in this guide, do let me know. I aim to keep this as understandable and accurate as possible.
Subscribe to:
Posts (Atom)