DSA errors, tips and tricks - discuss
Moderator: Zyx
Forum rules
Please read the Forum rules and policies before posting.
Please read the Forum rules and policies before posting.
DSA errors, tips and tricks - discuss
Maybe get a discussion going about DSAs - any errors and how to diagnose them, any tricks to make DSAs easier to use
The first thing to say is always use the timer trace when something strange happens...you can try to follow the logic of your code, and usually find where the wheels are coming off quickly enough. Open using notepad and always use the 'find' option to zoom in to certain words if you have alot of activity going on - the name of the particular filter, a certain key 'type' value you know should be appearing, etc. Common things you can spot are stack overflows (if a command isn't geting used right, chances are it is leaking values, especially in a recurrisve loop). Get the hang of what the trace is saying, and diagnosing becomes so much simpler
Also, if you get a DSA error and not sure where to start, be logical - start from the beginning and make sure each step works and move on to the next. Sometimes where the wheels are coming off can be because a bad value was fed much earlier into the array, or a rogue literal from earlier is combining with another error you would otherwise spot (like a stack underflow)
Errors:
I already stated a few in a thread to addf, but here's some of the many I've managed to generate through stupidity
Stack underflows: an error message shown when CSB crashes. Caused if there is a variable missing from the stack when you enter a command. Either you have simply forgot to put in a value (easy to do with long commands like &move) or some other function isn't providing the right information. I personally also get it because I usually increment using a '&1+' which requires one variable, and I always put '&+ instead, which adds two together to increment
Stack overflows: an error message shown before CSB crashes. You need to be generating a large amount of values to the stack to do this, and usually is the sign of a recursive loop not breaking out of itself, that is hemoraging (however you spell it) values onto the stack each cycle. Or, in other words, usually you have two problems, to stop the loop, and then you will probably want to work out why you are leaving values on the stack instead of them being used up in the first place!
Game freezes: If the game simply freezes in place, this is the sign that a DSA is locked in an infinite loop. This will be because you have missed out a '?' in a conditional jump so it always jumps, you are not reaching a target value to break out of the loop, or you simple have a jump command pointing to the wrong place.
Something happening all the time: Watch out for those pesky '?' in front of conditional jumps. Also, watch out for simple literal checks like &< for 'less than'.
Something never happens: Again it could be the above, but also make sure you are actually checking the values or situations you think you are. The syntax for &Param and any other check like &monster is reversed. Or, in other words you might think you are filling twelve memory arrays starting from 1' with party information, but in reality you are just assigning the first party variable to '12', and thus any checks you are making will be to garbage numbers. It is also hideously easy to forget to do '&@' when checking the value of an array - so you can be comparing a figure to '0' all the time, not comparing a figure to the contents of array '0'
Tips:
I personally always like to keep a single line of code in each DSA (usually 0T3) free as a noop.It makes it quick to know how to break out of the DSA or a gosub loop - just use JT3!
If you are doing complex code, it is a good idea while you are right in it and know exactly where logical breaks are to add the phrase 'L0 ?JT3' to the code. Currently it will do nothing, but it is very quick to then delete the '?' during debugging and create a break, and restore the ? to remove the break again.
You can, in a small way, comment your DSA code. CSBwin's error checking for parameters is quite good, and any parameter called it knows doens't exist will just be ignored and a zero generated instead. So if you insert the line 'lm lu lm lm ly ld le la lt lh' it will be allowed as viable code, and just generates a set of zeroes to the stack if it is actually acted upon. Whereas you can now remember that weird line of code was the one that killed mummies. Personally I use this kind of small comments in certain states (in unusaed lines) or at the end of a DSA function as reminders
Eh, I've typed to much to say too littel - anyone got any errors they've generated that they think other people might too, or have any cool tricks for writing code?
The first thing to say is always use the timer trace when something strange happens...you can try to follow the logic of your code, and usually find where the wheels are coming off quickly enough. Open using notepad and always use the 'find' option to zoom in to certain words if you have alot of activity going on - the name of the particular filter, a certain key 'type' value you know should be appearing, etc. Common things you can spot are stack overflows (if a command isn't geting used right, chances are it is leaking values, especially in a recurrisve loop). Get the hang of what the trace is saying, and diagnosing becomes so much simpler
Also, if you get a DSA error and not sure where to start, be logical - start from the beginning and make sure each step works and move on to the next. Sometimes where the wheels are coming off can be because a bad value was fed much earlier into the array, or a rogue literal from earlier is combining with another error you would otherwise spot (like a stack underflow)
Errors:
I already stated a few in a thread to addf, but here's some of the many I've managed to generate through stupidity
Stack underflows: an error message shown when CSB crashes. Caused if there is a variable missing from the stack when you enter a command. Either you have simply forgot to put in a value (easy to do with long commands like &move) or some other function isn't providing the right information. I personally also get it because I usually increment using a '&1+' which requires one variable, and I always put '&+ instead, which adds two together to increment
Stack overflows: an error message shown before CSB crashes. You need to be generating a large amount of values to the stack to do this, and usually is the sign of a recursive loop not breaking out of itself, that is hemoraging (however you spell it) values onto the stack each cycle. Or, in other words, usually you have two problems, to stop the loop, and then you will probably want to work out why you are leaving values on the stack instead of them being used up in the first place!
Game freezes: If the game simply freezes in place, this is the sign that a DSA is locked in an infinite loop. This will be because you have missed out a '?' in a conditional jump so it always jumps, you are not reaching a target value to break out of the loop, or you simple have a jump command pointing to the wrong place.
Something happening all the time: Watch out for those pesky '?' in front of conditional jumps. Also, watch out for simple literal checks like &< for 'less than'.
Something never happens: Again it could be the above, but also make sure you are actually checking the values or situations you think you are. The syntax for &Param and any other check like &monster is reversed. Or, in other words you might think you are filling twelve memory arrays starting from 1' with party information, but in reality you are just assigning the first party variable to '12', and thus any checks you are making will be to garbage numbers. It is also hideously easy to forget to do '&@' when checking the value of an array - so you can be comparing a figure to '0' all the time, not comparing a figure to the contents of array '0'
Tips:
I personally always like to keep a single line of code in each DSA (usually 0T3) free as a noop.It makes it quick to know how to break out of the DSA or a gosub loop - just use JT3!
If you are doing complex code, it is a good idea while you are right in it and know exactly where logical breaks are to add the phrase 'L0 ?JT3' to the code. Currently it will do nothing, but it is very quick to then delete the '?' during debugging and create a break, and restore the ? to remove the break again.
You can, in a small way, comment your DSA code. CSBwin's error checking for parameters is quite good, and any parameter called it knows doens't exist will just be ignored and a zero generated instead. So if you insert the line 'lm lu lm lm ly ld le la lt lh' it will be allowed as viable code, and just generates a set of zeroes to the stack if it is actually acted upon. Whereas you can now remember that weird line of code was the one that killed mummies. Personally I use this kind of small comments in certain states (in unusaed lines) or at the end of a DSA function as reminders
Eh, I've typed to much to say too littel - anyone got any errors they've generated that they think other people might too, or have any cool tricks for writing code?
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
DSAs can be simple (one line of code = cool effect you can't do elsewhere), I just wanted to see if there was a large pool of knowledge I oculd boil down to common bullet point so that anyone wanting to do something quick could have a simple look up table. I think anyone who used DSAs heavily will know the stupid mistakes thye make, or have the time to check stuff out
I had a mistake to fix, but I didn't know where. So I did a trace (got a trace000.txt file) and saw the problem. My pad created a 0 timer with a clear message that is never processed! Now I have to figure out why. The important part of the trace, with notes, is below.
What's happening is I'm stepping onto 5 pads that should create timers for 0 seconds and then instantly resolve in order. They target DSA's, so some DSA stuff happens too. When I clear "DSA Return Party to Start of Time Warp after 100 beats," whatever the state(0 or 1, the only ones I use), it ought to do this:
LB &1+ SB
Later when I do LB &1- SB it takes paramB 'negative,' which was not intended.
...
MoveParty forward from 05(13,1a)
Object ffff stepped Off pressure pad 03dc 05(13,1a)
Object ffff stepped On pressure pad 03e4 05(12,1a)
000035 timer create 00e 05 DLY=0000 06 00 12 1f 02 00 be7afbd1 Set 0x04 in DB at 05(12,1f)02
Object ffff stepped On pressure pad 03e5 05(12,1a)
///////////////////////////////////////////////////////////////this doesn't ever resolve?////////////////////////
000035 timer create 00f 05 DLY=0000 06 00 12 1f 00 01 be7afbd1 Clear 0x01 in DB at 05(12,1f)00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Object ffff stepped On pressure pad 03e6 05(12,1a)
000035 timer Byte9 00f 05 DLY=0000 06 00 12 1f 00 00 be7afbd1 Set 0x01 in DB at 05(12,1f)00
Object ffff stepped On pressure pad 03e7 05(12,1a)
000035 timer create 010 05 DLY=0000 06 00 0e 1c 02 00 be7afbd1 Set 0x04 in DB at 05(0e,1c)02
Object ffff stepped On pressure pad 03e8 05(12,1a)
000035 timer create 011 05 DLY=0000 05 00 00 00 00 00 be7afbd1
000035 timer Process 007 00 DLY=0000 20 f1 03 0b 06 cd be7afbd1
000035 timer create 007 00 DLY=0050 25 f1 03 0b 00 cd 991c09c8
000035 timer Process 009 00 DLY=0000 20 f1 06 0a 04 cd 991c09c8
000035 timer create 009 00 DLY=0050 25 f1 06 0a 00 cd a4b76833
000035 timer Process 00c 00 DLY=0000 20 f1 07 09 08 cd a4b76833
000035 timer create 00c 00 DLY=0050 25 f1 07 09 00 cd 099b2302
000035 timer Process 00e 05 DLY=0000 06 00 12 1f 02 00 099b2302 Set 0x04 in DB at 05(12,1f)02
DSA Return Party to Start of Time Warp after 100 beats State 1 MSG 6
(0)Execute DSA at 5(18,31) master at 5(18,31) state=1,msg=6
NOOP ()
(0)RETURN ()
///////////////////////////////////////////////////////////////should resolve here, right?///////////////////////////////
000035 timer Process 00f 05 DLY=0000 06 00 12 1f 00 00 099b2302 Set 0x01 in DB at 05(12,1f)00
DSA Return Party to Start of Time Warp after 100 beats State 0 MSG 0
(0)Execute DSA at 5(18,31) master at 5(18,31) state=0,msg=0
LOAD DOLLAR (5727)
LOAD BigInteger 65536 (5727 65536)
&+ (71263)
MESSAGE SET delay=100, 5(18,31)1
000035 timer create 00e 05 DLY=0064 06 00 12 1f 01 00 099b2302 Set 0x02 in DB at 05(12,1f)01
()
LOAD DOLLAR (5727)
MESSAGE TOGGLE delay=100, 5(18,31)0
000035 timer create 00f 05 DLY=0064 06 00 12 1f 00 02 099b2302 Toggle 0x01 in DB at 05(12,1f)00
()
(0)RETURN ()
000035 timer Process 010 05 DLY=0000 06 00 0e 1c 02 00 099b2302 Set 0x04 in DB at 05(0e,1c)02
DSA Repeat action every 100 beats State 0 MSG 6
(0)Execute DSA at 5(14,28) master at 5(14,28) state=0,msg=6
LOAD Parameter B = 0 (0)
&1+ (1)
STORE Parameter B = 1 ()
(0)RETURN ()
000035 timer Process 011 05 DLY=0000 05 00 00 00 00 00 099b2302
Drawing decoration
...
What's happening is I'm stepping onto 5 pads that should create timers for 0 seconds and then instantly resolve in order. They target DSA's, so some DSA stuff happens too. When I clear "DSA Return Party to Start of Time Warp after 100 beats," whatever the state(0 or 1, the only ones I use), it ought to do this:
LB &1+ SB
Later when I do LB &1- SB it takes paramB 'negative,' which was not intended.
...
MoveParty forward from 05(13,1a)
Object ffff stepped Off pressure pad 03dc 05(13,1a)
Object ffff stepped On pressure pad 03e4 05(12,1a)
000035 timer create 00e 05 DLY=0000 06 00 12 1f 02 00 be7afbd1 Set 0x04 in DB at 05(12,1f)02
Object ffff stepped On pressure pad 03e5 05(12,1a)
///////////////////////////////////////////////////////////////this doesn't ever resolve?////////////////////////
000035 timer create 00f 05 DLY=0000 06 00 12 1f 00 01 be7afbd1 Clear 0x01 in DB at 05(12,1f)00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Object ffff stepped On pressure pad 03e6 05(12,1a)
000035 timer Byte9 00f 05 DLY=0000 06 00 12 1f 00 00 be7afbd1 Set 0x01 in DB at 05(12,1f)00
Object ffff stepped On pressure pad 03e7 05(12,1a)
000035 timer create 010 05 DLY=0000 06 00 0e 1c 02 00 be7afbd1 Set 0x04 in DB at 05(0e,1c)02
Object ffff stepped On pressure pad 03e8 05(12,1a)
000035 timer create 011 05 DLY=0000 05 00 00 00 00 00 be7afbd1
000035 timer Process 007 00 DLY=0000 20 f1 03 0b 06 cd be7afbd1
000035 timer create 007 00 DLY=0050 25 f1 03 0b 00 cd 991c09c8
000035 timer Process 009 00 DLY=0000 20 f1 06 0a 04 cd 991c09c8
000035 timer create 009 00 DLY=0050 25 f1 06 0a 00 cd a4b76833
000035 timer Process 00c 00 DLY=0000 20 f1 07 09 08 cd a4b76833
000035 timer create 00c 00 DLY=0050 25 f1 07 09 00 cd 099b2302
000035 timer Process 00e 05 DLY=0000 06 00 12 1f 02 00 099b2302 Set 0x04 in DB at 05(12,1f)02
DSA Return Party to Start of Time Warp after 100 beats State 1 MSG 6
(0)Execute DSA at 5(18,31) master at 5(18,31) state=1,msg=6
NOOP ()
(0)RETURN ()
///////////////////////////////////////////////////////////////should resolve here, right?///////////////////////////////
000035 timer Process 00f 05 DLY=0000 06 00 12 1f 00 00 099b2302 Set 0x01 in DB at 05(12,1f)00
DSA Return Party to Start of Time Warp after 100 beats State 0 MSG 0
(0)Execute DSA at 5(18,31) master at 5(18,31) state=0,msg=0
LOAD DOLLAR (5727)
LOAD BigInteger 65536 (5727 65536)
&+ (71263)
MESSAGE SET delay=100, 5(18,31)1
000035 timer create 00e 05 DLY=0064 06 00 12 1f 01 00 099b2302 Set 0x02 in DB at 05(12,1f)01
()
LOAD DOLLAR (5727)
MESSAGE TOGGLE delay=100, 5(18,31)0
000035 timer create 00f 05 DLY=0064 06 00 12 1f 00 02 099b2302 Toggle 0x01 in DB at 05(12,1f)00
()
(0)RETURN ()
000035 timer Process 010 05 DLY=0000 06 00 0e 1c 02 00 099b2302 Set 0x04 in DB at 05(0e,1c)02
DSA Repeat action every 100 beats State 0 MSG 6
(0)Execute DSA at 5(14,28) master at 5(14,28) state=0,msg=6
LOAD Parameter B = 0 (0)
&1+ (1)
STORE Parameter B = 1 ()
(0)RETURN ()
000035 timer Process 011 05 DLY=0000 05 00 00 00 00 00 099b2302
Drawing decoration
...
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
Have you set the global setting that
allows ALL timers to be delivered?
If you look closely, you will see that
timer 'e' is delivered to your DSA, then
timer 'f' is delivered to your DSA. Those
are the two timers that you created.
The 'Clear' to 05(12,1f) was created.
Then the 'Set' to 05(12,1f) came along
but did not create a timer.....it simply
modified the existing timer 'f' that was
already present. (Byte 9 modified).
MOEOVER You cannot expect
timers to be delivered in the same order you
create them
Timers that expire in a single tick of the
clock are delivered in arbitrary order
If you want to send two messages to a
DSA in the same tick of the clock and the
order of arrival is important, then you better
do something different. In this case, you
could send a 'toggle 0' which your DSA
could interpret to mean 'Clear' then 'Set'.
By the way. Congratulations on understanding
these things well enough to do some
real, root-level debugging.
allows ALL timers to be delivered?
If you look closely, you will see that
timer 'e' is delivered to your DSA, then
timer 'f' is delivered to your DSA. Those
are the two timers that you created.
The 'Clear' to 05(12,1f) was created.
Then the 'Set' to 05(12,1f) came along
but did not create a timer.....it simply
modified the existing timer 'f' that was
already present. (Byte 9 modified).
MOEOVER You cannot expect
timers to be delivered in the same order you
create them
Timers that expire in a single tick of the
clock are delivered in arbitrary order
If you want to send two messages to a
DSA in the same tick of the clock and the
order of arrival is important, then you better
do something different. In this case, you
could send a 'toggle 0' which your DSA
could interpret to mean 'Clear' then 'Set'.
By the way. Congratulations on understanding
these things well enough to do some
real, root-level debugging.
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
By the way......
Perhaps we should add some examples of
DSA to the wiki. Does anyone have some
simple things that might be useful?
Sequential puzzle? Detecting particular
party members? Simple inter-level relays?
Detecting possession of a particular dagger?
Modifying monster generator delay? Giving
a character a special talent (Eat Axe?)?
Other?
Maybe I could document one or two along
with annotated traces to show how they work
internally.
Perhaps we should add some examples of
DSA to the wiki. Does anyone have some
simple things that might be useful?
Sequential puzzle? Detecting particular
party members? Simple inter-level relays?
Detecting possession of a particular dagger?
Modifying monster generator delay? Giving
a character a special talent (Eat Axe?)?
Other?
Maybe I could document one or two along
with annotated traces to show how they work
internally.
Now I see why the one was just an edit. It's because it was sent to the same location, right? should be easy to fix.
I don't know much about timers. I just discovered their workings by looking at the code. But when I use multiple pressure pads on the same spot, they always do what they do in the order they are arranged. Is this arbitrary order what you get when you create multiple timers from one line of DSA code?You cannot expect timers to be delivered in the same order you create them
Timers that expire in a single tick of the
clock are delivered in arbitrary order
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
I'll say it again. Messages to be deliveredTyGuy wrote:they always do what they do in the order they are arranged
on the same tick of the clock get delivered
in an unpredictable order. If you rely
on their being delivered in the order they
were created (or any other predictable order)
then your cries of 'BUG' will be responded
to with the words: "I told you so."
I should have said "unpredictable".Is this arbitrary order what you get
when you create multiple timers
"This arbitrary order" is not a sensible
phrase. There is no "arbitrary order". An
arbitrary order implies that some order has
been decided upon in an arbitrary manner.
But it haas not There is no attempt to
order the messages except to guarantee that
messages timed to arrive at DIFFERENT TIMES
are guaranteed to arrive with the earlier ones
first. Messages timed to arrive at the SAME
time arrive in totally unpredictable order.
by "unpredictable", you mean the delivery order of the messages A, B, C and D at the same time is either:
-completely random (repeating the process will always cause the different order: ABCD, BDAC, DABC, BADC, etc), or
-totally unknown (repeating the process will always cause the same order; say DBCA every time)?
-completely random (repeating the process will always cause the different order: ABCD, BDAC, DABC, BADC, etc), or
-totally unknown (repeating the process will always cause the same order; say DBCA every time)?
Spoiler
(\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/)
Spoiler
(@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@)
Spoiler
(>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<)
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
They are random. In the same sense
that the random number generator
produces random numbers. If you
play CSB twice, you will find that some
objects are in different places because
of the random motion of those gigglers
that you never see. Of course, that
motion is created by a pseudo-random
process. The random number generator
is totally predictable. But when playing
CSB you cannot predict where those
objects will be. It is too complex.
Like predicting the weather two weeks
in advance. If you could solve the
quantum mechanical equations for the
enitire universe then you could tell whether
or not a raindrop will fall on your nose
in two weeks.
Likewise, if you tell me on which tick of the
clock you will press each mouse button
and what the x/y coordinates are at that
time then we can determine in advance
the order that the messages will be received.
We would do this by emulating the execution
of CSBwin because it is too complicated to
figure out any other way. So in that sense,
it is not random. It can be determined by
running the program in advance and seeing
what happens. In fact, this is exactly what
happens when you play one of CSBwin's
'movies'. We run the program again with
exactly the same input and we get exactly
the same results. BUT....if you change
ANYTHING (like press a mouse button
one-sixth of a second later) then the movie
will not run. It will crash because things
happen differently. Perhaps those messages
will get delivered BADC instead of ABCD.
So, to answer your question: No, it is not
"completely random". Neither is it "totally
unknown". It is like flipping a coin. If you
know everthing about the coin, how it was
flipped, the properties of the surface it is
to land upon, the air currents in the room,
and so on, then you can predict heads or tails.
Good luck.
that the random number generator
produces random numbers. If you
play CSB twice, you will find that some
objects are in different places because
of the random motion of those gigglers
that you never see. Of course, that
motion is created by a pseudo-random
process. The random number generator
is totally predictable. But when playing
CSB you cannot predict where those
objects will be. It is too complex.
Like predicting the weather two weeks
in advance. If you could solve the
quantum mechanical equations for the
enitire universe then you could tell whether
or not a raindrop will fall on your nose
in two weeks.
Likewise, if you tell me on which tick of the
clock you will press each mouse button
and what the x/y coordinates are at that
time then we can determine in advance
the order that the messages will be received.
We would do this by emulating the execution
of CSBwin because it is too complicated to
figure out any other way. So in that sense,
it is not random. It can be determined by
running the program in advance and seeing
what happens. In fact, this is exactly what
happens when you play one of CSBwin's
'movies'. We run the program again with
exactly the same input and we get exactly
the same results. BUT....if you change
ANYTHING (like press a mouse button
one-sixth of a second later) then the movie
will not run. It will crash because things
happen differently. Perhaps those messages
will get delivered BADC instead of ABCD.
So, to answer your question: No, it is not
"completely random". Neither is it "totally
unknown". It is like flipping a coin. If you
know everthing about the coin, how it was
flipped, the properties of the surface it is
to land upon, the air currents in the room,
and so on, then you can predict heads or tails.
Good luck.
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
As an aside----
This may be the reason that the developers
of DM did not allow two messages for
the same destination at the same time.
For example, if one message opened a
door and the next closed it, then there
would be no way to determine the final
state of the door because there is no way
to determine which message would be
processed first. So, instead of producing
that second message, they modified the
first message to be like the second. That
has the effect of delivering the messages
in the order created. Of course, in the
case of a counter or something sensitive
to the NUMBER of messages, it breaks.
This may be the reason that the developers
of DM did not allow two messages for
the same destination at the same time.
For example, if one message opened a
door and the next closed it, then there
would be no way to determine the final
state of the door because there is no way
to determine which message would be
processed first. So, instead of producing
that second message, they modified the
first message to be like the second. That
has the effect of delivering the messages
in the order created. Of course, in the
case of a counter or something sensitive
to the NUMBER of messages, it breaks.
I still don't understand what kind of messages we're referring to. I've done a test to illustrate my point, but if it is the wrong one let me know.
I put two teleporters pointing to eachother. Inactive, visible. One has apple.
Two pressure pads on top of eachother: 1st sets a teleporter, 2nd clears the same teleporter. (they should send these messages to the same tick, no?)
A button to target a DSA which does LA MS* LA MC*, where param A points to the teleporter.
When stepped on, the pressure pads only clear the teleporter (if it's on). The DSA also only clears. Apple stays where it is. This doesn't seem at all random, pseudorandom, unknown, arbitrary, etc.
I also tried it with pushbuttons, and with separate DSA's that do LA MS* and LA MC* separately, triggered in that order (but on the same tick). I tried switching the order of triggering, so the order is MC then MS, and in that case it only sets the teleporter.
Conclusion: When the same action(step on switch, push button or DSA) would do 2 things to a location, it only does the last thing. It overides the first action with the second. It is not random.
I put two teleporters pointing to eachother. Inactive, visible. One has apple.
Two pressure pads on top of eachother: 1st sets a teleporter, 2nd clears the same teleporter. (they should send these messages to the same tick, no?)
A button to target a DSA which does LA MS* LA MC*, where param A points to the teleporter.
When stepped on, the pressure pads only clear the teleporter (if it's on). The DSA also only clears. Apple stays where it is. This doesn't seem at all random, pseudorandom, unknown, arbitrary, etc.
I also tried it with pushbuttons, and with separate DSA's that do LA MS* and LA MC* separately, triggered in that order (but on the same tick). I tried switching the order of triggering, so the order is MC then MS, and in that case it only sets the teleporter.
Conclusion: When the same action(step on switch, push button or DSA) would do 2 things to a location, it only does the last thing. It overides the first action with the second. It is not random.
- Sophia
- Concise and Honest
- Posts: 4249
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
I hope you don't mind me chiming in...
Of course, you can override this behavior. What you're really overriding, then, I believe, is the game engine changing the existing message to be like the new message. This means you can now send whatever messages you like, but then they must be careful of this:
Let me address one other thing.
Let's take an extremely primitive engine that only allows three timer entries at a given time. At the beginning, it looks like this.
If you step on a pressure pad that says to open a door, say something like this happens (I'll omit the targets and times for the sake of simplicity, say all of these messages are directed at the same target and due to arrive at the same time):
Now, let's say you want to deliver an open and close message at the same time. Well, from everything being empty, this too would appear fairly logical.
So, it shows up in order, right?
Well, after those messages have been delivered, we go back to:
However, there's a difference. 1 and 2 have been filled. For efficiency, the engine probably isn't going to start its search for an empty slot from the beginning every time-- it'll go from where it left off last time-- and it will just wrap around when it can't find one past the maximum number. So, that means, it's going to start at slot 3 this time. If we try to put in an open/close combination again, just like before, we'll end up with:
Do you see the problem?
The CLOSE is now in before the OPEN, because the game first put the OPEN into slot 3 (because that was where it "left off" when it was creating timer entries), wrapped around, and then put the CLOSE into slot 1.
Granted, the real program has a much larger buffer, but it's also doing a lot more complicated things. This is the general principle why it might appear to work some/most of the time, but it can't be trusted to work all the time, and if you do rely on this behavior, your dungeon will (no can, may, or might about it) break eventually.
A message is simply how one object in the dungeon tells another object what to do, like a button telling a door to open, or a pressure pad telling a pit to close, and so on. A DSA can also send these out. You probably understand this already, but that's all it is.TyGuy6 wrote:I still don't understand what kind of messages we're referring to.
TyGuy6 wrote:When the same action(step on switch, push button or DSA) would do 2 things to a location, it only does the last thing. It overides the first action with the second.
This is why.Paul Stevens wrote:the developers of DM did not allow two messages for the same destination at the same time.
Of course, you can override this behavior. What you're really overriding, then, I believe, is the game engine changing the existing message to be like the new message. This means you can now send whatever messages you like, but then they must be careful of this:
Paul Stevens wrote:Messages to be delivered on the same tick of the clock get delivered in an unpredictable order.
Let me address one other thing.
From the way the code is structured, it seems like timer entries are just pushed at the end of a buffer. This means that more often than not, things will stay in sequence. However, there's absolutely no guarantee where they'll end up. It depends on where there's a "slot" in the buffer.TyGuy6 wrote:I use multiple pressure pads on the same spot, they always do what they do in the order they are arranged.
Let's take an extremely primitive engine that only allows three timer entries at a given time. At the beginning, it looks like this.
Code: Select all
1 [EMPTY] 2 [EMPTY] 3 [EMPTY]
Code: Select all
1 [OPEN] 2 [EMPTY] 3 [EMPTY]
Code: Select all
1 [OPEN] 2 [CLOSE] 3 [EMPTY]
Well, after those messages have been delivered, we go back to:
Code: Select all
1 [EMPTY] 2 [EMPTY] 3 [EMPTY]
Code: Select all
1 [CLOSE] 2 [EMPTY] 3 [OPEN]
The CLOSE is now in before the OPEN, because the game first put the OPEN into slot 3 (because that was where it "left off" when it was creating timer entries), wrapped around, and then put the CLOSE into slot 1.
Granted, the real program has a much larger buffer, but it's also doing a lot more complicated things. This is the general principle why it might appear to work some/most of the time, but it can't be trusted to work all the time, and if you do rely on this behavior, your dungeon will (no can, may, or might about it) break eventually.
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
And----
If you have not selected the option to
deliver ALL messages, then things
become perfectly predictable. But, as I
said above, you pay the price of delivering
only one message instead of the two that
you sent. This could break algorithms
that count things, for example. I prefer
to deliver all messages and worry about
the sequence myself.
Sophia's example is very close to the
truth. The queue is not linear, it is
a binary tree. The example is not perfect
because the actual problem can occur
before the queue fills. It can happen when
an entry is placed on the right side of the
tree and the next entry is placed on the
left side. But the result is identical.
If you have not selected the option to
deliver ALL messages, then things
become perfectly predictable. But, as I
said above, you pay the price of delivering
only one message instead of the two that
you sent. This could break algorithms
that count things, for example. I prefer
to deliver all messages and worry about
the sequence myself.
Sophia's example is very close to the
truth. The queue is not linear, it is
a binary tree. The example is not perfect
because the actual problem can occur
before the queue fills. It can happen when
an entry is placed on the right side of the
tree and the next entry is placed on the
left side. But the result is identical.
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
Adamo asked me to post this:
http://dianneandpaul.net/CSBwin/MsgDeliveryDemo.rar
Here are his words:
http://dianneandpaul.net/CSBwin/MsgDeliveryDemo.rar
Here are his words:
Adamo wrote: I made a littele demo showing people "in practice"
the differences caused between delivering ONE and
ALL messages. Could you publish it so
people could easily (?) understand the matter?
When you unpack the "demo.rar" file, there are
two folders: "disable" and "enable". They are
absolutely identical, except that in one case ALL
the messages are delivered at the same time,
and in the second case all the messages are
NOT delivered at the same time.
This cause in different behaviour of the doors
(named "crushers") at level zero.
So: start a game from "disabled" folder, push both
the Eye swithes and observe both the doors. Then
start a game from "enabled" folder and do the same.
Thank you!
PS. Someone mentioned here on the forum about something like an online DSA database. I don`t remember where (encyclopedia?). If it exist, I could add there my DSAs (well, they`re not exactly mine- there were made by Paul, Sophia and Beo) with a short description.
PS. Someone mentioned here on the forum about something like an online DSA database. I don`t remember where (encyclopedia?). If it exist, I could add there my DSAs (well, they`re not exactly mine- there were made by Paul, Sophia and Beo) with a short description.
Spoiler
(\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/)
Spoiler
(@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@)
Spoiler
(>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<)
hmm...
please don't forget that there are neophyte custom designers like me with very low coding skills who have quite hard times to get into all this.
As for DSA:
a FAQ for noobs like me starting with
-what is a DSA?
-what tools are needed / editing suggestions
-point and click yourself to the first "Hello World"
-what is a filter / how to make effects global and local?
-expl. of the DSA syntax and its logic implied by the engine.
data base:
- examples
- tools (instruction on Dungeon editing in general)
- common and wanted DSAs to come
basic:
-how to change color of a text
-how to create special clone items and custom attack options ("invoke" on ice winds, lousy T-shirt, etc.)
- ...
tricks / substitutions:
-DSA instead of having a giggler in an enclosed room triggering a pressure plate to create a random effect (problem movie playback).
-DSA instead of using "party holding specific item" and several clone rooms with invisible teleporters to creating a NPC giving quests.
-instead of the coin slot solution: how to create a shop (thread about it and an example already exists)
- ...
example of a advanced (and kind of always wanted in DM) DSA:
- a char holding a bow collects arrows from the ground and puts them into the pouch (again a DSA is needed to use them automatically) and the quiver, a char with a sling will do the same for stones, a char with with a close-combat weapon will only collect darts/shurikan etc.
- being able to hold a long range weapon without using both hands (right hand for the projectile), using a flask instead or being able to use a flask for potion that is placed in the inventory.
Tips already written (Beo):
Errors:Stack underflows:Stack overflows:Game freezes:Something happening all the time:Something never happens:Tips:
examples by Adamo/Paul/Zyx/...
please don't forget that there are neophyte custom designers like me with very low coding skills who have quite hard times to get into all this.
(As said) The DMwiki would be a good place to add this as Conflux is mysterious and wonderful not only because of it's outstanding design, but also because of the excessive use of DSAs. But any other place would be fine too (private page, encyclopedia, whereever). Generally there is quite a bit of confusion for newbies on how to get the latest versions of whatever tool/editor/program. The Encyclopedia covers most of this (which is great!), but still there are some things leftover or at least quite tricky to find. (most recent version of CSBwin, differences in open and hardwired clones of DM, bugfix for ADGE, etc.)Maybe get a discussion going about DSAs - any errors and how to diagnose them, any tricks to make DSAs easier to use
As for DSA:
a FAQ for noobs like me starting with
-what is a DSA?
-what tools are needed / editing suggestions
-point and click yourself to the first "Hello World"
-what is a filter / how to make effects global and local?
-expl. of the DSA syntax and its logic implied by the engine.
data base:
- examples
- tools (instruction on Dungeon editing in general)
- common and wanted DSAs to come
basic:
-how to change color of a text
-how to create special clone items and custom attack options ("invoke" on ice winds, lousy T-shirt, etc.)
- ...
tricks / substitutions:
-DSA instead of having a giggler in an enclosed room triggering a pressure plate to create a random effect (problem movie playback).
-DSA instead of using "party holding specific item" and several clone rooms with invisible teleporters to creating a NPC giving quests.
-instead of the coin slot solution: how to create a shop (thread about it and an example already exists)
- ...
example of a advanced (and kind of always wanted in DM) DSA:
- a char holding a bow collects arrows from the ground and puts them into the pouch (again a DSA is needed to use them automatically) and the quiver, a char with a sling will do the same for stones, a char with with a close-combat weapon will only collect darts/shurikan etc.
- being able to hold a long range weapon without using both hands (right hand for the projectile), using a flask instead or being able to use a flask for potion that is placed in the inventory.
Tips already written (Beo):
Errors:Stack underflows:Stack overflows:Game freezes:Something happening all the time:Something never happens:Tips:
examples by Adamo/Paul/Zyx/...
not mine. They were made by others. The examples of DSAs I use are spread through the forum. What I can do is only to get them all and add with a description how to use them to something like a DSA database, if exists.examples by Adamo/Paul/Zyx/...
I don`t have an idea HOW they work. I only use some of them.
Spoiler
(\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/) (\__/)
Spoiler
(@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@) (@.@)
Spoiler
(>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<) (>s<)
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
I think what is needed is a small
number of SIMPLE examples with
very complete annotation. The
examples proposed by TOMI (three
messages above here) are much too
complex for such examples.
I will add a inter-level relay to the
wiki. This has to be approximately
the simplest thing a person can do
and might be the equivalent of the
'Hello, World' of C-Programming fame.
The trick to making it useful is to
add enough comment/traces/etc.
I will copy my existing documentation
to the wiki so people can insert
questions and clarifications.
number of SIMPLE examples with
very complete annotation. The
examples proposed by TOMI (three
messages above here) are much too
complex for such examples.
I will add a inter-level relay to the
wiki. This has to be approximately
the simplest thing a person can do
and might be the equivalent of the
'Hello, World' of C-Programming fame.
The trick to making it useful is to
add enough comment/traces/etc.
I will copy my existing documentation
to the wiki so people can insert
questions and clarifications.
- Paul Stevens
- CSBwin Guru
- Posts: 4321
- Joined: Sun Apr 08, 2001 6:00 pm
- Location: Madison, Wisconsin, USA
I added DSA Lesson001 to the wiki.
Starting at the front page you will see GAMES/
ConfluxIII/CSBwin and that will take you there.
This is for interested beginners and I hope you
will look at it and report back your reaction and
questions and suggestions. After we have given
this some time to settle, we can add Lesson002
which will talk about sending messages to/from
a DSA.
zyx: I will be happy to post your examples but
it will be some time before I can annotate them.
I doubt that you have any really simple examples.
Starting at the front page you will see GAMES/
ConfluxIII/CSBwin and that will take you there.
This is for interested beginners and I hope you
will look at it and report back your reaction and
questions and suggestions. After we have given
this some time to settle, we can add Lesson002
which will talk about sending messages to/from
a DSA.
zyx: I will be happy to post your examples but
it will be some time before I can annotate them.
I doubt that you have any really simple examples.
a few words from me:
It helps.
I could follow the text and now I understand
how the stack gets loaded(push and pull) and
what &+ and &* means! very helpful.
The screenshots are a nice addition.
To the example dungeon DSAlesson001
the dsa dsa-compute 15 has its code
in S0.
does that mean it gets only executed
when the origin of the messages to the dsa
sends a SET message?
target of pressure plate is dsa
pressure plate is origin of dsa
When you look at the pressure pad it has
these properties:
http://img501.imageshack.us/img501/7940 ... 454eo5.png
each time the pressure pad is
stepped on (S0 =SET)
the S0 code will be executed(number 15 generated/
in the end is 15 put on the stack)
because the pressure pad is linked to the dsa
and not only once, we would have 15, 15 15
for 3 times stepping onto the stack.
When is the stack full? how many numbers can be put onto
until it is too high?
note it takes a while to get to know how to put a dsa
into connection to a door or pressure plate.
but it seems easy.
and there is only one stack, right?
therefore you can use a dsa to store numbers ,
like 15 in some dsa for future references.
maybe some line of code that says
L15
I do not see what we can accomplish by having
the number 15 stored .
Maybe we can use it in another dsa?
anyway it is beginning to make sense , and
all in all I vote to continue the lessons.
It helps.
I could follow the text and now I understand
how the stack gets loaded(push and pull) and
what &+ and &* means! very helpful.
The screenshots are a nice addition.
To the example dungeon DSAlesson001
the dsa dsa-compute 15 has its code
in S0.
does that mean it gets only executed
when the origin of the messages to the dsa
sends a SET message?
target of pressure plate is dsa
pressure plate is origin of dsa
When you look at the pressure pad it has
these properties:
http://img501.imageshack.us/img501/7940 ... 454eo5.png
each time the pressure pad is
stepped on (S0 =SET)
the S0 code will be executed(number 15 generated/
in the end is 15 put on the stack)
because the pressure pad is linked to the dsa
and not only once, we would have 15, 15 15
for 3 times stepping onto the stack.
When is the stack full? how many numbers can be put onto
until it is too high?
note it takes a while to get to know how to put a dsa
into connection to a door or pressure plate.
but it seems easy.
and there is only one stack, right?
therefore you can use a dsa to store numbers ,
like 15 in some dsa for future references.
maybe some line of code that says
L15
I do not see what we can accomplish by having
the number 15 stored .
Maybe we can use it in another dsa?
anyway it is beginning to make sense , and
all in all I vote to continue the lessons.
This is great!
Finally some basics to begin with.
Like zoom for the first time I kind of understood some DSA. Wow.
A more steep learning curve and much less frustating trial-and-error for all custom builders will be the result of this when its kind of up and running and someday complete.
It's true: Even without it everyone should be able to extract the needed information for custom building based on the things already there and without a wiki, but it is scattered and it -really- needs both patience and lots of time to get it and into it. Easy to miss things badly needed to get started if you're new and don't know about how it was built up historically. Lots of intersting stuff and examples on pauls site (not to mention the DSA discussed in the forum) that could now be focussed in the wiki.
I'd say 9 of 10 people are to shy to ask on the forum for help, and it ranges from people who simply don't get DM to run on their device to people who have the ability to master creating DSAs (not 'just' copy/pasting which is not that bad anyway), but can't find their way through the scattered information. It's a small community, but compared to other -much- larger ones, its powerful!
I wish I had more time...
(for me the most urgent task for the next days (weeks?) is to 'code' that encryption prog to create an unreadable-for-human-eyes strings.txt for CSBwin (a nice sideeffect of the translation thing Paul did for me, now used and not useless). It will be a great addition. In my custom instead of the seen a million times professions there will be Brawler, Hurler, Alchemist and Conjurer. And Alchemy pots instead of flasks, insect swarms instead of poison clouds, Heros instead of monsters... and and and time time time...
Finally some basics to begin with.
Like zoom for the first time I kind of understood some DSA. Wow.
A more steep learning curve and much less frustating trial-and-error for all custom builders will be the result of this when its kind of up and running and someday complete.
It's true: Even without it everyone should be able to extract the needed information for custom building based on the things already there and without a wiki, but it is scattered and it -really- needs both patience and lots of time to get it and into it. Easy to miss things badly needed to get started if you're new and don't know about how it was built up historically. Lots of intersting stuff and examples on pauls site (not to mention the DSA discussed in the forum) that could now be focussed in the wiki.
I'd say 9 of 10 people are to shy to ask on the forum for help, and it ranges from people who simply don't get DM to run on their device to people who have the ability to master creating DSAs (not 'just' copy/pasting which is not that bad anyway), but can't find their way through the scattered information. It's a small community, but compared to other -much- larger ones, its powerful!
I wish I had more time...
(for me the most urgent task for the next days (weeks?) is to 'code' that encryption prog to create an unreadable-for-human-eyes strings.txt for CSBwin (a nice sideeffect of the translation thing Paul did for me, now used and not useless). It will be a great addition. In my custom instead of the seen a million times professions there will be Brawler, Hurler, Alchemist and Conjurer. And Alchemy pots instead of flasks, insect swarms instead of poison clouds, Heros instead of monsters... and and and time time time...