Flag initializing/blind-clearing, also Adventure of Sam
Moderators: Commodore, Zenith Nadir
- Kjorteo
- ^o.O^
- Posts: 432
- Joined: Sat Feb 28, 2004 10:59 am
- Location: Kjorteoville or something
- Contact:
Flag initializing/blind-clearing, also Adventure of Sam
This is half my attempt to counter the "ZZT is dead" rumor, and half because it's awesome.
I HAVE INVENTED SOMETHING, I think. At the very least, I haven't seen it mentioned in ZEOL or anything like that before and no one I asked in #rawr (because that was the last time I asked, shut up) seemed to know about it, so it could be something new.
This only works in very controlled circumstances for now, but perhaps the idea could be expanded upon. Who knows.
PROBLEM: You want the user to be able to ?+enter a flag for some reason (you have a game with an inventory system, you want them to enter a password to start world 2 of a multi-world game, etc.) but the user is a dumbass who typos the thing they're trying to enter. Now you have a flag you can't clear because you have no way of knowing what the hell they even entered, and leaving it there is potentially hazardous if you have a lot of flags and it pushes you over the flag limit. You want to clear any and all hypothetical flags and start over but there is no #CLEAR ALL command.
SOLUTION: I have come up with a way to be able to blind-clear potential flags by basically turning ZZT's flag limit against itself. ZZT, of course, uses a last-in, first-out method when at the limit and having to overwrite flags. If you set flags 1 through 10, in that order, and then set flag 11, it will clear flag 10 to make room for it. If you then set flag 12, it will clear flag 11 to make room for it, so you're left with 1-9 and 12.
Knowing this, one can pre-initialize a board by setting ten different flags right away, before the player is allowed to do anything. Then, when the player is asked to ?+enter something, it will overwrite the tenth flag. If the user is asked to ?+enter something again, it will overwrite the first thing the user ?+entered, and so on. Essentially, the user is limited to having one flag at a time at this point. When all of this is done and you'd like to move on with a completely flag-free blank slate, simply set the tenth flag again (overwriting the last thing the user ?+entered) and then clear all ten flags you set, thus leaving you with no flags whatsoever. It doesn't matter what the user may have ?+entered--everything is perfectly 100% clear now.
Due to the need to have ten flags set beforehand, applications for this are (for now, unless someone else invents a way to expand on this) limited to very controlled circumstances, ideally very early on in one's game. However, it is perfect for, say, making the user ?+enter a password to start world 2 of a multi-world game, with no worry of "what if the user messed up while entering the password, are there residual flags there?" You are guaranteed a clean slate when the game actually starts.
I have attached a proof-of-concept one-board world. It is incredibly ugly, because I didn't make it in the form of a presentation to show anyone else or anything. Primarily I just made it for my own twisted experimentation so I could figure this out, and when it actually worked, I uploaded it here as-is. Look through the code and figure it out, it shouldn't be too hard. The best way to test the world is to try to manually ?+set flagp through flagt, then have the debug object attempt to blind-clear all flags. It should work, even though a careful examination of its code reveals that all the blind-clearing does is set and then clear flaga through flagj.
http://home.comcast.net/~kjorteo/flagtest.zzt
Also, I basically had to come up with this because I was having this exact problem with the password for getting into the second world of Adventure of Sam; with this method to take care of it, I can begin work on world 2 in earnest. So, consider this a progress report on that, too.
In fact, speaking of progress updates, ADVENTURE OF SAM NEWS NO ONE CARES ABOUT YAY
So world one is completely finished and relatively debugged, including external playtesting from DavidN, Dr. Dos, Slither, and Xaq, who I basically consider my official playtesting team at this point. (Too many testers is basically just releasing the game early to everyone who cares, and I want to save at least some surprise and interest for the general release, whereas too few limits their ability to actually find bugs. I'm content with these guys, I think.) World two was stalled while I tried to work out the password thing, but now that that's taken care of, I have the title screen and the first couple of boards. Barring any unexpected twists, I expect this game to be three worlds when complete. There is a chance the second world might be a bit short, since there is a definite plot-relevant reason the switch between worlds two and three has to happen exactly when I plan for it to, even if there turns out to be more room in the second world when I get that far. The first world was definitely flirting with the filesize limit, though, and a few rooms had to be cut to make it fit.
I implemented some basic shading for the letters in the first world's title screen. This is about as pretty as the game is going to get. I'm not an artist. I don't make pretty graphics in ZZT like Nadir did back when he made games. I do engine stuff. Don't expect much more than KevEdit gradients to pretty up the actual game, but at least the gameplay will do some cool things, and at least I tried a little bit on the title screen.
The title screen for the second world is a color swap of the first, because I wanted to make it clear that this is the same game, just, you know, the next part of it. Neither color scheme for the first two worlds have any particular meaning beyond just what I thought would look good, but the third world (whose title screen will follow the same approach) will have a color scheme that is significant.
I HAVE INVENTED SOMETHING, I think. At the very least, I haven't seen it mentioned in ZEOL or anything like that before and no one I asked in #rawr (because that was the last time I asked, shut up) seemed to know about it, so it could be something new.
This only works in very controlled circumstances for now, but perhaps the idea could be expanded upon. Who knows.
PROBLEM: You want the user to be able to ?+enter a flag for some reason (you have a game with an inventory system, you want them to enter a password to start world 2 of a multi-world game, etc.) but the user is a dumbass who typos the thing they're trying to enter. Now you have a flag you can't clear because you have no way of knowing what the hell they even entered, and leaving it there is potentially hazardous if you have a lot of flags and it pushes you over the flag limit. You want to clear any and all hypothetical flags and start over but there is no #CLEAR ALL command.
SOLUTION: I have come up with a way to be able to blind-clear potential flags by basically turning ZZT's flag limit against itself. ZZT, of course, uses a last-in, first-out method when at the limit and having to overwrite flags. If you set flags 1 through 10, in that order, and then set flag 11, it will clear flag 10 to make room for it. If you then set flag 12, it will clear flag 11 to make room for it, so you're left with 1-9 and 12.
Knowing this, one can pre-initialize a board by setting ten different flags right away, before the player is allowed to do anything. Then, when the player is asked to ?+enter something, it will overwrite the tenth flag. If the user is asked to ?+enter something again, it will overwrite the first thing the user ?+entered, and so on. Essentially, the user is limited to having one flag at a time at this point. When all of this is done and you'd like to move on with a completely flag-free blank slate, simply set the tenth flag again (overwriting the last thing the user ?+entered) and then clear all ten flags you set, thus leaving you with no flags whatsoever. It doesn't matter what the user may have ?+entered--everything is perfectly 100% clear now.
Due to the need to have ten flags set beforehand, applications for this are (for now, unless someone else invents a way to expand on this) limited to very controlled circumstances, ideally very early on in one's game. However, it is perfect for, say, making the user ?+enter a password to start world 2 of a multi-world game, with no worry of "what if the user messed up while entering the password, are there residual flags there?" You are guaranteed a clean slate when the game actually starts.
I have attached a proof-of-concept one-board world. It is incredibly ugly, because I didn't make it in the form of a presentation to show anyone else or anything. Primarily I just made it for my own twisted experimentation so I could figure this out, and when it actually worked, I uploaded it here as-is. Look through the code and figure it out, it shouldn't be too hard. The best way to test the world is to try to manually ?+set flagp through flagt, then have the debug object attempt to blind-clear all flags. It should work, even though a careful examination of its code reveals that all the blind-clearing does is set and then clear flaga through flagj.
http://home.comcast.net/~kjorteo/flagtest.zzt
Also, I basically had to come up with this because I was having this exact problem with the password for getting into the second world of Adventure of Sam; with this method to take care of it, I can begin work on world 2 in earnest. So, consider this a progress report on that, too.
In fact, speaking of progress updates, ADVENTURE OF SAM NEWS NO ONE CARES ABOUT YAY
So world one is completely finished and relatively debugged, including external playtesting from DavidN, Dr. Dos, Slither, and Xaq, who I basically consider my official playtesting team at this point. (Too many testers is basically just releasing the game early to everyone who cares, and I want to save at least some surprise and interest for the general release, whereas too few limits their ability to actually find bugs. I'm content with these guys, I think.) World two was stalled while I tried to work out the password thing, but now that that's taken care of, I have the title screen and the first couple of boards. Barring any unexpected twists, I expect this game to be three worlds when complete. There is a chance the second world might be a bit short, since there is a definite plot-relevant reason the switch between worlds two and three has to happen exactly when I plan for it to, even if there turns out to be more room in the second world when I get that far. The first world was definitely flirting with the filesize limit, though, and a few rooms had to be cut to make it fit.
I implemented some basic shading for the letters in the first world's title screen. This is about as pretty as the game is going to get. I'm not an artist. I don't make pretty graphics in ZZT like Nadir did back when he made games. I do engine stuff. Don't expect much more than KevEdit gradients to pretty up the actual game, but at least the gameplay will do some cool things, and at least I tried a little bit on the title screen.
The title screen for the second world is a color swap of the first, because I wanted to make it clear that this is the same game, just, you know, the next part of it. Neither color scheme for the first two worlds have any particular meaning beyond just what I thought would look good, but the third world (whose title screen will follow the same approach) will have a color scheme that is significant.
Last edited by Kjorteo on Sat May 09, 2009 6:31 am, edited 3 times in total.
"You're alive," said the maker, and smiled at the aardvark.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
maybe for an inventory system you could have flags set to empty, that is #set empty1 - empty9, but that sounds like a lot of overhead.
For the password I suggest something different that I've seen before and have used (seen by few) in wolfenstein, which is to have the use ?- instead of ?+. I used ?-i for my inventory engine. it eliminates the need to hold shift too. you can't ruin things by using - unless the user somehow makes a typo that clears an essential flag, so they could try all the passwords they want and until they clear the password flag.
awesome to hear you're making progress too.
For the password I suggest something different that I've seen before and have used (seen by few) in wolfenstein, which is to have the use ?- instead of ?+. I used ?-i for my inventory engine. it eliminates the need to hold shift too. you can't ruin things by using - unless the user somehow makes a typo that clears an essential flag, so they could try all the passwords they want and until they clear the password flag.
awesome to hear you're making progress too.
*POW* *CLANK* *PING*
- Kjorteo
- ^o.O^
- Posts: 432
- Joined: Sat Feb 28, 2004 10:59 am
- Location: Kjorteoville or something
- Contact:
That's a good approach, too. I think mine works better for what I need it to do in my game, though. Still, I might keep yours in mind as another option if the circumstances are ever different. Thanks!
Also, I was going to post some more AoS screenshots into the screenshot thread because I felt like it was time for an update, but it was locked, so I went back and edited my post here.
Also, I was going to post some more AoS screenshots into the screenshot thread because I felt like it was time for an update, but it was locked, so I went back and edited my post here.
"You're alive," said the maker, and smiled at the aardvark.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
- Quantum P.
- Level 17 Accordion Thief
- Posts: 1433
- Joined: Fri Sep 12, 2003 1:41 am
- Location: Edmonds, WA
- Contact:
This is very clever.
Extending this to a whole game does have some overhead as Commodore mentioned, but it isn't really bad. You just #set empty1-empty9, and assign each flag to a slot:So redcard is always associated with empty4 (you'd have to make a table of these to keep them straight). This somewhat limits how you can use flags, but you can work around it by using the same slot for multiple flags. It's a tradeoff of complexity for a more bulletproof engine, which may be useful if you expect (or fear) extensive flag tinkering by the player.
Using ?- instead of ?+ is perhaps more pragmatic for in-game stuff, but I really like Kjorteo's method for password entry. The ?- method just keeps the user from screwing things up, whereas the Kjorteo method also allows the engine to determine when the user has entered any password:This allows the password engine to respond to the user if they get the password wrong. The ?- engine or the regular ?+ engine would just sit idly as if nothing had happened.
Also, nice title screens! Good choice of colors and pleasing geometry are often a good substitute for being able to draw realistic pictures.
Extending this to a whole game does have some overhead as Commodore mentioned, but it isn't really bad. You just #set empty1-empty9, and assign each flag to a slot:
Code: Select all
#clear empty4
#set redcard
. . .
#clear redcard
#set empty4
Using ?- instead of ?+ is perhaps more pragmatic for in-game stuff, but I really like Kjorteo's method for password entry. The ?- method just keeps the user from screwing things up, whereas the Kjorteo method also allows the engine to determine when the user has entered any password:
Code: Select all
#set flaga
. . .
#set flagi
:reset
#set flagj
:loop
/i#if flagj loop
#if ossifrage good
WRONG PASSWORD, MORON
/i#reset
:good
Proceed.
Also, nice title screens! Good choice of colors and pleasing geometry are often a good substitute for being able to draw realistic pictures.
- Kjorteo
- ^o.O^
- Posts: 432
- Joined: Sat Feb 28, 2004 10:59 am
- Location: Kjorteoville or something
- Contact:
Oooh. I like the idea of trading empty1-empty9 slots with actual flags to basically keep a tamper-proof set of flags throughout the whole game. The problem there--and this isn't insurmountable, but it's tricky and can mess things up if the programmer forgets about it--is that setting a new flag and leaving it there with no further modification defeats the entire purpose of this, which is that the last flag set is the first one out when there's a conflict. You'd have to #set and clear empty10, then #clear empty4 and #set redcard, and finally (optionally?) set #empty10 again, or else the empty4/redcard slot is no longer protected. However, this seems simple enough to deal with so long as the programmer doesn't forget to do so. Overall, I like where this is going.
"You're alive," said the maker, and smiled at the aardvark.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
- Quantum P.
- Level 17 Accordion Thief
- Posts: 1433
- Joined: Fri Sep 12, 2003 1:41 am
- Location: Edmonds, WA
- Contact:
I believe the flag replacement algorithm is not based on the order flags are set, but on the positions of the flags in ZZT's array of flag slots. Running the following code:
...Results in the following (internal flag state recorded via savegames and viewed from KevEdit):
If the last flag set is always the first one out, then ADAMS should have overwritten JOHN. But instead, ADAMS overwrote J.
When setting flags, I suspect ZZT simply puts the flag in the first empty slot it sees (the one with the lowest number). If there are no empty slots, then it puts the flag in slot 10, overwriting whatever used to be there.
Code: Select all
#set a
#set b
. . .
#set i
#set j
/i/i/i/i
#clear b
/i/i/i/i
#set john
/i/i/i/i
#set adams
If the last flag set is always the first one out, then ADAMS should have overwritten JOHN. But instead, ADAMS overwrote J.
When setting flags, I suspect ZZT simply puts the flag in the first empty slot it sees (the one with the lowest number). If there are no empty slots, then it puts the flag in slot 10, overwriting whatever used to be there.
- Kjorteo
- ^o.O^
- Posts: 432
- Joined: Sat Feb 28, 2004 10:59 am
- Location: Kjorteoville or something
- Contact:
Wow. That is highly relevant information. My password system as is still works in light of that, fortunately, but that certainly changes how to expand on this, if anyone was to do so.
"You're alive," said the maker, and smiled at the aardvark.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
<Kjorteo> "yiff"
<gbelo> Wanna yiff.
<Kjorteo> yes
<gbelo> No no no.
your tactic QP reminds me of this TSR I tried to make liver program, which basically you'd press a button and it would show you the internal state of zzt, flags, number of objects on the board and the like. He was all about visual basic though and I think dos TSRs would have to be coded in C or pascal or something like that.
*POW* *CLANK* *PING*
An inventory based game that kept track of the player's free bag slots with something like torches could conceivably keep 9 flags all the time. An inventory management object to be kept somewhere on the screen would look something like:To use an item:To pick up an item:
Code: Select all
@bag
#cycle 1
:x
#end
:out
#give torches 1
#if not empty9 a
#if not empty8 b
#if not empty7 c
#if not empty6 d
#if not empty5 e
#if not empty4 f
#if not empty3 g
#if not empty2 h
#set empty1
#x
:a
#set empty9
#x
:b
#set empty8
#x
:c
#set empty7
#x
:d
#set empty6
#x
:e
#set empty5
#x
:a
#set empty4
#x
:f
#set empty3
#x
:g
#set empty2
#x
:in
#take torches 1 all:nobag
#if not empty8 clear empty9
#if not empty7 clear empty8
#if not empty6 clear empty7
#if not empty5 clear empty6
#if not empty4 clear empty5
#if not empty3 clear empty4
#if not empty2 clear empty3
#if not empty1 clear empty2
#clear empty1
#x
:nobag
INVENTORY IS FULL!
Code: Select all
#clear item
#bag:out
Code: Select all
#bag:in
/i#set item
'Picked-up-item code here, #zap touch etc.
:nobag
#end