Sk2sadat - an alternative compiler for ScottKit source code

Hi,

To add another option for people who want to write material for the Scott Adams system, I made a compiler for ScottKit source code files: https://github.com/pdxiv/sk2sadat

This differs from the official ScottKit compiler in that it adds some of the optimizations and fixes that have been discussed in the forum. Additionally, I hope that the error messages are more helpful.

One big advantage of sk2sadat over the official ScottKit is the possibility to fit much more data into the game files with little/no extra effort.

It should be fully usable right now but there will no doubt be as-of-yet undiscovered bugs, and I’ll work on resolving the known issues in the near future.

Big thanks to ahope1, auraes, heasm66 and jcompton for valuable discussions, suggestions and valued opinions.

6 Likes

I’m intrigued. Right now for SALAD #2 (which I’ll get back to soon, I swear!) I would stick with SK because as much as I gripe about the balky handling of long actions and the occasional need to trick SK with the dual-swap_room maneuver, I prefer that convenience to the idea of rolling my own continues.

Hm! - Perhaps I should prioritize implementing “long actions” then :grinning:
I have two possible solutions to the problem in mind, but if I need to do it soon, I’ll pick the simpler one that’s closest to how ScottKit does it. In theory, it’s possible to take it further to allow up to 8 conditions in an action and an infinite number of commands, but the devil is in the details.

2 Likes

No rush on my account… as far as I can tell, as long as I’m willing to keep doing the swap dance, I’m fine.

I gather that that main advantage of your compiler is smoothing the path to >99 messages. I think it’s truest to the SALAD premise if I stick with 99 for Women Beware Women SALAD #2.

If we’re not all sick of the premise by then and I’m still inspired to continue the series, maybe there can be some sort of “Deluxe SALAD” game that uses more messages. :slight_smile:

1 Like

sk2sadat now supports long actions! :partying_face:
It was more tricky than I imagined, so my hat’s off to Mike Taylor on implementing it in ScottKit.

I never actually understood the “swap dance”, tbh. I’m naïvely hoping that it’s something that sk2sadat doesn’t require (however it may work). :slight_smile:

All the more respect to you for that! The number of messages is the primary benefit, yes. It’s worth mentioning that sk2sadat doesn’t currently support disabling the message optimizations, which may actually drive up the total number of messages to >99 in some situations (with no negative impact).

A more minor advantage is that it also allows more nouns than the 149 noun limit, for objects which aren’t used in actions.

The ambition is that it should never generate a corrupt game file, and instead terminate with an informative error message when it encounters a limitation or something it can’t handle.

Sick of seventies style Shakespeare text adventures? Never!

2 Likes

An open question:
I want compatibility with ScottKit code to be maintained, but should some additional features be added, for the convenience of the programmer? I have two small features in mind that would simplify my life at least:

  1. Being able to write subaction instead of occur 0% for subactions (prepended by a continue command in a previous action/occur).
  2. Being able to name flags. For instance in The Count, flag #2 is used to signify sleep, and it would make the code easier to understand if set_flag 2 could instead (optionally) be written as set_flag sleep.

Any opinions? I see the value of being able to read existing ScottKit source code files, but at the same time there are some simple “quality of life” improvements that would make things nicer but I also don’t want to fragment things.

Are you offering free candy with no consequences? That is, “everything that’s written to ScottKit standard still Just Works, and if you use new SK2 syntax that Just Works too”? If so…

1 feels like a "go right ahead if you want to but it doesn’t bother me because I don’t want to have to manually use continue" feature.

2 would definitely be useful and appreciated, although I would be a little curious how you’d roll it out:

Would we have to declare label-to-number conversions at the top of the file? (define_flag sleep = 2 or whatever, then set_flag sleep)?

Would the compiler handle those conversions behind the scenes (and remember to skip the darkness flag!) but we’d be able to mix and match?

Would the compiler handle those conversions behind the scenes but we’d have to use only-numbers or only-labels to avoid the chance of overlap?

The goal would be, to be 100% “backwards compatible” with normal/old ScottKit code, making the additions entirely optional to use in your code.

Using “subactions” is a bit of a pain no matter what, sadly. Perhaps there could be an elegant way to do this differently, but nothing springs to mind at the moment.

It would not require you to explicitly define which flag number corresponds to what flag “name” and it would all be handled “under the hood”. This is how I would probably do it:

Initially, when parsing a source code file you would have a “flag reservation table” that’s predefined to look like this:

           0 => 0
          15 => 15
      "dark" => 15
          16 => 16
"empty_lamp" => 16

When an action/occurrence containing flag statements is encountered, entries are added to this table.

occur
    set_flag 3
    set_flag sleep

…and the “flag reservation table” would look like this:

           0 => 0
          15 => 15
      "dark" => 15
          16 => 16
"empty_lamp" => 16
           3 => 3
     "sleep" => undefined

Once all the actions have been read, all the “undefined” values in the table will be assigned the first unique available value, and the final table would look like this:

           0 => 0
          15 => 15
      "dark" => 15
          16 => 16
"empty_lamp" => 16
           3 => 3
     "sleep" => 1

When the time comes to translate the code to an old-fashioned Scott Adams DAT file, any instances of “sleep” will be translated to “0”.

1 Like

I pretty much agree with @jcompton but be sure to document it. There is a problem if the “language” diverge so much that games written in it no longer is able to compile in ScottKit. A suggestion how to handle this could be:

  1. Let the new syntax generate compiler warnings that inform that this source diverges from ScottKit syntax and won’t compile in it.
  2. Or, only make the new syntax available only with a compiler switch to make the programmer aware that new syntax is used.

Anyway, just my two cents…

1 Like

Thanks, having a --skplus (or something like that) commandline switch to activate this behavior is the best approach I think.

This seems like a good time to ask:

Why not just fix up the existing ScottKit and push the changes?

1 Like

It’s just my personal preference… but I like Perl better than Ruby.

I struggled with that decision. There were several reasons for making an entirely new compiler.

I wanted pretty big changes that I didn’t know how hard they would be to implement. I don’t know Ruby and frankly, writing in Perl 5 in the year 2021 is bad enough, and I don’t want to spend a massive amount of time learning how to solve problems in yet another language that is (in my very personal opinion) on the way out. The quickest way to get something out the door (I believed) and into the hands of people was to do it from scratch in Perl.

I really like ScottKit, but I don’t believe in having a “monoculture” either. By making something from scratch, I could experiment with concepts while I was writing it and not be tied down how that particular implementation was done.

All that said, if Mike Taylor thinks the optimizations and syntax extensions are good to have, I wouldn’t mind creating a PR for ScottKit, when I know that they actually work, assuming I can figure out how to do it in Ruby without too much effort :slight_smile:

1 Like

I’m having trouble making it works. First, I had to install ReadOnly perl library.

Then, when I compile the source code, it puts out text.

32767
1
-1
18
3

etc

Which I’m sure will need further compilation. But I have no idea how to do it.

Anyway, typing SCOTTFREE TEST2.DAT gives me “Initial quote expected” error.

So, how do I get this thing running?

1 Like

Interesting! I want my programs to be as self-contained as possible and I expected ReadOnly to be included by default in most Perl installations these days, otherwise I wouldn’t have used it. Perhaps I should get rid of it, if it isn’t usually present by default on some systems. What platform are you on?

Regarding "Initial quote expected”, I think that’s a bug related to item nouns. Good find! I’ll try to get that fixed during the day.

It appears when the noun is in quotes, as with “lamp” in the below example.

item lit_lamp "lit lamp"
	called "lamp" nowhere

It produces a rogue extra quote character in the item declaration in the data file as follows:

"lit lamp/"LA/" 0

Until this is fixed, this bug can be avoided by simply not using quotes around the noun term as follows instead:

item lit_lamp "lit lamp"
	called lamp nowhere

…and this will produce the correct output in the data file:

"lit lamp/LAM/" 0

I’m tracking the progress of this in this GitHub issue:

Edit: Fixed the above issue but uncovered another bug where if the start statement isn’t present, the game will start in the “nowhere room”, rather than in the first room you declare.
For example, right now if you want to start the game in a room labeled “cave”, you need to add:

start cave

…to avoid starting the game in the “nowhere room”.

I’m on Raspberry Pi . I did the no quote thing, and start keyword, and it works fine.

Another problem I found is when I type “score”, I get “Floating point exception”. I get this whether there’s item in treasure room or not. Presumably, the first room is a treasure room, instead of nowhere?

Another good catch! I can’t try it at the moment, but I assume that this is a similar issue as the “start” statement problem. It should be possible to work around by manually specifying “treasury cave” (assuming that there is a room with ID “cave” that you want to use as a treasury room). It should be easy to fix in a similar way to the “start” thing and I’ll try to have these issues corrected later today.

Sorry. Still doesn’t work. Same error. It doesn’t seem to matter where I do it.

treasury spec doesn’t seem to do anything.

All I did was going thru the tutorial files on ScottKit. I find it strange that this gives me trouble?

Edit:
Oh, I think the error is because I neglected to specify a treasure! I set the coin as treasure, and no problem!
Still need “treasury” keyword, though.

I notice Carp library as well. I ended installing it also, although I don’t see any changes in behavior.

I guess Raspberry Pi isn’t prioritizing Perl installation.

About Carp and Readonly: I try to write Perl code according to “Perl Best Practices” to make the code as readable and maintainable as possible, and it explicitly recommends that you use Carp and Readonly. I realize that sk2sadat doesn’t actually Carp here even though I include it, so that can be ripped out. Readonly isn’t really a big thing either. I think it’s more important to have the program running out of the box on a Raspberry Pi without the user having to mess about with external dependencies. Thanks for bringing this up.

I don’t mind talking about these things here, but possibly discussions around some of these things could be better addressed with “GitHub Issues” since that’s closer to where the code lives anyway :slight_smile:

2 Likes