Page 1 of 1

The real problem with the Automizer

Posted: Sat Oct 03, 2015 4:12 pm
by Lord Estraven
... IMO is that it wants to be an imperative, procedural programming language.

I'm serious. Right now it uses JSON, a data format. And any moderately functional automizer profile quickly develops into a nightmare of deeply nested, branching potentialities. It winds up completely inscrutable.

But even a complex automizer profiler could be better expressed by switch statements, or even if-then-else statements. Much more expressive, much less verbose. And it's not like we have grave security concerns that discount Turing-complete languages.

e.g. right now my generic "destroy unenchanted equipment" rule looks like this

Code: Select all

[
  {
    "action": "destroy",
    "condition": {
      "conditions": [
        {
          "conditions": [
            {
              "symbol": ")",
              "type": "symbol"
            },
            {
              "symbol": "(",
              "type": "symbol"
            },
            {
              "symbol": "]",
              "type": "symbol"
            },
            {
              "symbol": "[",
              "type": "symbol"
            },
            {
              "symbol": "/",
              "type": "symbol"
            },
            {
              "symbol": "\\",
              "type": "symbol"
            },
            {
              "symbol": "|",
              "type": "symbol"
            }
          ],
          "type": "or"
        },
        {
          "conditions": [
            {
              "status": "average",
              "type": "status"
            },
            {
              "status": "bad",
              "type": "status"
            }
          ],
          "type": "or"
        }
      ],
      "type": "and"
    },
    "module": "ToME",
    "name": "Destroy Average Stuff"
  }
]
Now let's say we did this in something like Python.

Code: Select all

if object.symbol in [ "[", "]", "(", ")", "|", "/", "\" ]:
    if object.status in [ "average", "bad" ]:
        object.destroy
Much better, I'd say. Less confusing to edit by hand, probably even for computer novices. Plus it becomes trivial to throw in other arbitrary requirements:

Code: Select all

if object.symbol in [ "[", "]", "(", ")", "|", "/", "\" ]:
    if object.status in [ "average", "bad" ]:
        if not "Dark Sword" in object.name:
            object.destroy
With the automizer, that requires a whole lot of messing around.

What say you all?

Re: The real problem with the Automizer

Posted: Mon Oct 05, 2015 11:33 am
by Yottle
This looks like a good idea to me.

I once tried to write a universal automizer (which isn't that hard to do conceptually) but realized that I needed a separate set of rules for every class and race. Something that could handle conditional logic more robustly would be better.

Re: The real problem with the Automizer

Posted: Mon Oct 05, 2015 3:15 pm
by AnonymousHero
Yottle wrote:This looks like a good idea to me.

I once tried to write a universal automizer (which isn't that hard to do conceptually) but realized that I needed a separate set of rules for every class and race. Something that could handle conditional logic more robustly would be better.
There's no way that embedding anything like Python is going to happen in my fork. The whole point was to get away from the ridiculous amount of incidental complexity of integrating two languages. :)

That said... I've never been particularly happy about the way the automatizer worked. I think the system in e.g. Entroband/PosChengband is much better and it's pretty simple to understand. The downside is that might perhaps be a little special-casey.

The squelch system in current Angband is probably the best of breed, IMO, because it a) reflects what the player actually wants, namely to ignore items, b) it's simple UI-wise, and c) doesn't actually irreversibly destroy items if you're careless. However, with the ridiculous number of drops in T2, I don't think it's quite feasible to use it. :/. Perhaps a variant which actually destroys items when you walk onto them would be acceptable.

(However, it's probably not something I'm interested in implementing ATM, nor do I have the time, honestly.)

Re: The real problem with the Automizer

Posted: Mon Oct 05, 2015 6:48 pm
by Lord Estraven
I kind of figured. Ah well. :?

I might attempt to DIY here, not sure it's worth the effort though. Rather put the effort into another variant.

Re: The real problem with the Automizer

Posted: Mon Oct 05, 2015 8:09 pm
by AnonymousHero
FWIW, I think it might be a fun little programming learning experience (if you're so inclined) to implement a parser for something like PosChengband (using some sort of parser generator).

I also don't think it would be too hard to implement something quite Pythonesque (like your strawman proposal).

Re: The real problem with the Automizer

Posted: Tue Oct 06, 2015 3:42 am
by Zizzo
Well, there was my old replacement auto.lua that wrapped a more readable language around the internal XML-esque automatizer data format. Your example rule, for instance, could have been written in ATP (as I dubbed the language) as:

Code: Select all

rule "Destroy Average Stuff" destroy
  if symbol = "[", "]", "(", ")", "|", "/", "\"
     and status = "average", "bad"
     and not (name = "Dark Sword");
Unfortunately, it sounds like things have changed too much for it to be useful anymore.

Re: The real problem with the Automizer

Posted: Tue Oct 06, 2015 1:09 pm
by Lord Estraven
Wowza. Cool!

That would work, I think, up to version 2.3.9-ah (at best). Not past that, because it uses JSON rather than XML after that version.

Edit: BTW, @AnonymousHero, I'm curious - did the original implement its own XML parser or something?

Re: The real problem with the Automizer

Posted: Tue Oct 06, 2015 4:48 pm
by AnonymousHero
Lord Estraven wrote: Edit: BTW, @AnonymousHero, I'm curious - did the original implement its own XML parser or something?
Yup. Or, rather... calling it a "parser" would be generous. It was a regexp-based thing that didn't actually understand real XML, it just understood the very small subset that the automatizer used. I can't recall if it also relied on the particular formatting (e.g. "no newlines between attributes" and such), but I think it might have done.

(I couldn't find any reasonable XML parsers for C++ at the time and so decided on JSON.)

Re: The real problem with the Automizer

Posted: Tue Oct 06, 2015 8:19 pm
by Lord Estraven
Naive, regex-based XML "parser", right... There but for the grace of God go I.

Anyway, I'm considering a go at the imperative automizer-script-thing. Never worked with parser generators before though. Googling up Flex/Bison, the syntaxes look like some bastard hybrid of Ruby, Haskell, and BNF... Though I feel like the main challenge would not be setting up the parser, so much as integrating the parser into the game in a meaningful and maintainable fashion.

(I guess the best/only way to do that, would be to have Flex and Bison invoked during the build process? Maintaining chunks of autogenerated, optimized C does not sound like fun.)

Re: The real problem with the Automizer

Posted: Sun Oct 11, 2015 3:49 pm
by AnonymousHero
Lord Estraven wrote:Googling up Flex/Bison, the syntaxes look like some bastard hybrid of Ruby, Haskell, and BNF... Though I feel like the main challenge would not be setting up the parser, so much as integrating the parser into the game in a meaningful and maintainable fashion.

(I guess the best/only way to do that, would be to have Flex and Bison invoked during the build process? Maintaining chunks of autogenerated, optimized C does not sound like fun.)
Yes, definitely -- if we're talking about parser generators they should be incorporated as a part of the build somehow. It's customary to actually have it as a "special" build target which is only called when explicitly asked for and to just include the generated files in the VCS repository -- so that "ordinary" users who just want to build from source can do so without installing bison/flex/whatever.

I'm not sure what's best when using C++ these days, but Boost.Spirit seemed interesting at least...

(I think there's a new-improved-C+11-ified-version of Boost.Spirit on the way, but I'm not sure what the status is on that. See http://boost-spirit.com/home/2015/05/16/spirit-3-0-0/ for a starting point.)

If we use a template-based solution, then all that's really needed is to include the headers (similar to how Bandit++ is incorporated)