MikeTaylor / scottkit

Scott Adams adventure toolkit: compile, decompile and play 80s-style adventure games
30 stars 10 forks source link

select_counter not working as expected #36

Open MikeTaylor opened 5 years ago

MikeTaylor commented 5 years ago

Craig Macfarlane reports:

--

Hi Mike,

Thanks for replying to my comment on ScottKit. Sorry that I’ve taken so long to reply but I was unaware that you had replied – I didn’t see any email alerting me to a response, so I must have some settings wrong or I need to check my spam filter (although your posts are getting through, e.g. etch-a-sketch, which is what prompted me to go back and check the comments section on ScottKit today).

I’ve attached a short script to test counter1. It performs as follows: At start of game displays “-1-1” despite setting counter1 to 5. Entering a direction (e.g. “w”) causes counter1 to count down but “-1 -1” is interspersed with actual counter1 values:

5 4 -1 -1 4 3 -1 -1 3 2 -1 -1 2 1 -1 -1 1 0 -1 -1 0 -1 -1 -1 ad infinitum.

If I comment out both ‘select_counter 1’ commands (i.e. use default counter) then it works normally. At start of game displays “54”. Entering a direction (e.g. “w”) causes counter to count down:

5 4 4 3 3 2 2 1 1 0 0 -1 -1 -1 ad infinitum.

--

And here is the source file:

# Global configuration
# ----------------------------------------------------------------------------
ident 210170
version 1
wordlen 4
maxload 6
start Room1
treasury Room1

# Welcome message and set counter 1
# ----------------------------------------------------------------------------
occur when !flag 1
    print "Test non-default counter 1"
    select_counter 1
    set_counter 5
    set_flag 1

# Room1
# ----------------------------------------------------------------------------
room Room1 "Room."
occur when at Room1
select_counter 1
print_counter #[for troubleshooting – yields value of 0]
dec_counter
print_counter #[for troubleshooting – yields value of -1]
MikeTaylor commented 5 years ago

According to https://github.com/MikeTaylor/scottkit/blob/master/docs/notes/Definition-scottfree-1.14.txt the definition of opcode 81 should be:

Select a counter. Current counter is swapped with backup counter

And the code in ScottFree v1.14 bears this out:

            case 81:
            {
                /* This is somewhat guessed. Claymorgue always
                   seems to do select counter n, thing, select counter n,
                   but uses one value that always seems to exist. Trying
                   a few options I found this gave sane results on ageing */
                int t=param[pptr++];
                int c1=CurrentCounter;
                CurrentCounter=Counters[t];
                Counters[t]=c1;
                break;
            }

So what we should be doing is copying the "current counter" value into the nominated numbered counter, and copying the value of that nominated numbered counter into the "current counter". The "current counter" should not itself be one of the numbered counters, but a separate special value the only one that can be directly set, augmented and tested.

MikeTaylor commented 5 years ago

... and that does seem to be exactly what we do:

        when 81 then which = args.shift
          @game.counter, @game.counters[which] =
            @game.counters[which], @game.counter
MikeTaylor commented 5 years ago

OK, so I think the current behaviour is correct — though more documentation would help.

On the initialisation (!flag 1):

    select_counter 1
    set_counter 5

The select_counter swaps the values of the current counter and counter 1, both of which are initially zero. Then it sets the current counter to 5.

Then before each turn this code runs:

select_counter 1
print_counter #[for troubleshooting – yields value of 0]
dec_counter
print_counter #[for troubleshooting – yields value of -1]

So on the first time through it swaps the current counter (value 5) with counter 1 (value 0), prints the value (0), decrements it, and prints the new value (-1).

And on the second time through, it swaps the current counter (value -1) with counter 1 (value 5), prints that value, decrements it, and prints the new value (4).

And on the third time through, it swaps the current counter (value 4) with counter 1 (value -1), prints that value, decrements it, and prints the new value (-2).

etc.

MikeTaylor commented 5 years ago

In conclusion, I think the simplest and safest way to use the counters is either:

MikeTaylor commented 5 years ago

Here's an example of the second approach: a one-room game containing a matchbook and a packet of mints. The former contains five matches, the latter contains three mints. You can examine either to see how many items it contains; and you can strike match or eat mint to decrement the numbers.

room home "house"
    exit north home

occur when !flag 1
    set_flag 1

    select_counter 1 # number of matches
    set_counter 5
    select_counter 1 # save

    select_counter 2 # number of mints
    set_counter 3
    select_counter 2 # save

item matchbook "matchbook" called matchbook

action examine matchbook when present matchbook
    print "There are"
    select_counter 1
    print_counter
    select_counter 1
    print "matches in the book"

action strike match when present matchbook
    print "I strike a match"
    print "There are now"
    select_counter 1
    dec_counter
    print_counter
    print "matches left"
    select_counter 1

item mints "pack of mints" called mints

action examine mints when present mints
    print "There are"
    select_counter 2
    print_counter
    select_counter 2
    print "mints in the packet"

action eat mint when present mints
    print "I eat a mint"
    print "There are now"
    select_counter 2
    dec_counter
    print_counter
    print "mints left"
    select_counter 2

Here's a sample transcript:

ringo:tmp$ scottkit -p two-counters.sck 
ScottKit, a Scott Adams game toolkit in Ruby.
(C) 2010-2017 Mike Taylor <mike@miketaylor.org.uk>
Distributed under the GNU GPL version 2 license.

I'm in a house
Obvious exits: North.
I can also see: matchbook, pack of mints

Tell me what to do ? examine matchbook
There are
5 matches in the book
Tell me what to do ? examine mints
There are
3 mints in the packet
Tell me what to do ? eat mind
I eat a mint
There are now
2 mints left
Tell me what to do ? examine mints
There are
2 mints in the packet
Tell me what to do ? eat mint
I eat a mint
There are now
1 mints left
Tell me what to do ? examine mints
There are
1 mints in the packet
Tell me what to do ? strike match
I strike a match
There are now
4 matches left
Tell me what to do ? examine matchbook
There are
4 matches in the book