pyAngband's thread

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • d_m
    Angband Devteam member
    • Aug 2008
    • 1517

    #31
    The second approach is nicer for writing borgs and things. It's the one I am more interested in, although it does require more work.
    linux->xterm->screen->pmacs

    Comment

    • Derakon
      Prophet
      • Dec 2009
      • 9022

      #32
      I think the second is likely better as well. You encapsulate the game state and then pass it off to a visualizer -- which might be headless in the case of the borg, or could be an OpenGL renderer for First-Person Angband, or a curses display for Angband-Over-SSH, etc. Basically you get a lot more flexibility in how the game is handled.

      Comment

      • Sirridan
        Knight
        • May 2009
        • 560

        #33
        I agree, I was partly hoping for a cop-out response so I would have an excuse to not work as hard, but alas, doing it now will take longer; but will be better in the long run.

        At least some things won't change the state of Angband itself (and if you don't know, I refer to the game core as Angband, and the display/input as the Client). Things like checking character stats, looking around, looking at inventory, basically informational stuff do not change the game state, so those are not so difficult to implement.

        Things like moving, shops, and such are a bit more tricky, but not too bad I'd wager.

        I was thinking each element on the game map has it's on ID, therefore the client can decide how to display that (prefs, etc) with a "default" pref that can be sent from Angband itself.

        Text and such would require special formatting inside to show what words are important or not. That or using an intelligent parser on the client side. Personally I like special formatting better... at least the thought of it, but a parser would probably be better, because at least for testing you won't get a bunch of text like:

        Code:
        "The (k:m t:'Yeek') hits you for (k:d t:'4') damage"
        k = kind (m = monster, d = damage), t = text
        Then again, if you use the formatting, you can change the layout of the message without having to change client parser code... But I'll worry about this later, for now it's easy enough to chug on along without worrying about formatting, because it could be added later

        Comment

        • Sirridan
          Knight
          • May 2009
          • 560

          #34
          Quick question, I have Angband running as a FSM right now. The client pushes keys onto Angband's internal key queue, and when the client calls Angband's run function, those keys are used up, and so on.

          What I'm trying to decide now is if I should continue this pattern (passing keys into Angband), or should I put some kind of link to the external inkey() function from the client so that Angband itself can get keys when it needs them?

          Angband getting its own keys would make some code a little easier, and wouldn't really cause too much coupling with the client, but it would add some. What do you all think?

          Comment

          • chris
            PosChengband Maintainer
            • Jan 2008
            • 702

            #35
            Originally posted by Sirridan
            Quick question, I have Angband running as a FSM right now. The client pushes keys onto Angband's internal key queue, and when the client calls Angband's run function, those keys are used up, and so on.

            What I'm trying to decide now is if I should continue this pattern (passing keys into Angband), or should I put some kind of link to the external inkey() function from the client so that Angband itself can get keys when it needs them?

            Angband getting its own keys would make some code a little easier, and wouldn't really cause too much coupling with the client, but it would add some. What do you all think?
            How about using a Command queue instead? Keys can be bound to commands arbitrarily (think Roguelike versus Standard, and also think Macros). This could offer richer scripting options too. Macros could be more than just sequences of keystrokes, but could become richer.

            Command could be:
            "Cast Spell - No arguments", and the game engine prompts for book, etc.

            or
            "Cast Spell - Heal Self". Game just casts the spell implied by the command arguments.

            Comment

            • Sirridan
              Knight
              • May 2009
              • 560

              #36
              Originally posted by chris
              How about using a Command queue instead? Keys can be bound to commands arbitrarily (think Roguelike versus Standard, and also think Macros). This could offer richer scripting options too. Macros could be more than just sequences of keystrokes, but could become richer.

              Command could be:
              "Cast Spell - No arguments", and the game engine prompts for book, etc.

              or
              "Cast Spell - Heal Self". Game just casts the spell implied by the command arguments.
              Sounds interesting, I think I know how I could do that too. I'll post results when I can (right now I'm working on the 'open' command since I have a working map now)

              Comment

              • chris
                PosChengband Maintainer
                • Jan 2008
                • 702

                #37
                Originally posted by chris
                "Cast Spell - No arguments", and the game engine prompts for book, etc.
                I guess maybe you were asking how the game prompts for a spellbook. My comment was intended to express dislike for the giant switch statement that dispatches off the user's keystroke, where case 'm' means cast a spell, etc.

                But some actions will need to prompt the user, and the issue is how to do that. In some respects, this should be the game client's task to implement, as it might be nice for the game engine to say: Here are a list of choices, go get a response from the user. Some clients might pop up a menu. Others might do significant work to emulate menus on a console. Others might allow rich hot keys. Some might be maintaining a buffer of keystrokes and first try to read the next key in the buffer ... whatever. But it would be nice for the game engine to have an abstraction barrier separating UI from logic.

                Game Engine:
                Ask the client for the next Command.
                Ask the command to Execute.

                Spell Command -> Command:
                Do I have arguments that indicate what spell to cast? If so, just cast it. If not, build a list of spell books and ask the game client to have the user pick one. Then ask the book to enumerate its spells, and again ask the client to have the user pick one. Then lookup the spell object and invoke it. (Aside: It would be nice if spellbooks where dynamic containers of spell objects, as this opens up the opportunity for customization, or scribe classes that copy scrolls into their spellbooks, etc.)

                Get Command -> Command:
                Pick up the object currently under the player and put it into inventory.

                etc.

                Sorry, I'm jumping into this thread a bit late ... I'll shut up now

                Comment

                • Sirridan
                  Knight
                  • May 2009
                  • 560

                  #38
                  Well that giant switch statement exists at some point, somewhere. BUT I can keep it out of the main game code, and stick it somewhere else.

                  Here's a rundown of what happens:

                  key comes in -> key passed to Angband -> Angband build's a command and puts that on the queue -> commands are processed as long as the player has the energy to do so

                  but yeah, I'll probably do something like this for the prompt:

                  Code:
                  def prompt(self, choices):
                      #if choices is an empty list, then it's a directional prompt, otherwise its a list of things
                      if(len(choices) > 0):
                          return self._client.select_prompt(choices)
                      else:
                          return self._client.direction_prompt()
                      return None
                  Where details of prompts are dealt with in the client

                  Comment

                  • Derakon
                    Prophet
                    • Dec 2009
                    • 9022

                    #39
                    Originally posted by Sirridan
                    Sounds interesting, I think I know how I could do that too. I'll post results when I can (right now I'm working on the 'open' command since I have a working map now)
                    Excellent news.

                    At some level you're going to have to map input to actions, but I do agree that this should be at the interface level, not the engine level. Not just roguelike vs. "standard" keysets, but also mouse input (clicking on buttons that the client shows the user), touchscreens, gestures, etc. are all things that the client would have to interpret for the engine anyway, and having the client have to say "Okay, the user just made the "cast spell" gesture, so I should map that to 'm' for the engine so it can map 'm' to "cast spell"" is just silly.

                    How's about this for interaction?

                    * Client passes Cast Spell action to Engine.
                    * Engine passes ObjectPrompt object back to Client. ObjectPrompt contains a list of valid targets for Cast Spell action (including spellbooks in inventory and on floor, in this case)
                    * Client shows selection to user, gets the user's choice, returns that choice to Engine.
                    * Engine passes ChoicePrompt to Client, asking Client to choose which spell is cast; Client prompts user, sends to Engine.
                    * Engine passes AimPrompt to Client, asking Client to choose where the spell is cast (or an ItemPrompt for casting on an item, etc.); Client prompts user for tile/direction, sends to Engine.

                    Prescripted responses to Prompts could be passed to the Engine; in that case, the Engine would match up Prompts to entries in the pregenerated response queue. For example, if the Client sends the Engine "cast spell, object target spellbook 1, choice target 1", then the Engine would skip the first two prompts as it already has responses, but would still send the AimPrompt to the Client.

                    Comment

                    • Sirridan
                      Knight
                      • May 2009
                      • 560

                      #40
                      Sounds like a good idea.

                      Although I loathe to let the client know about the inner workings of the game, I do believe now that the client should generate the commands. This is especially important for the possible use of different devices, which may manage input in different ways. Ports then become much easier.

                      Edit: And it's not like changing commands is a difficult port to make...

                      Comment

                      • d_m
                        Angband Devteam member
                        • Aug 2008
                        • 1517

                        #41
                        Sounds like you all are already in agreement, but I agree that the client should submit [action, arg, ...] objects rather than key presses. The current Angband scheme of mapping client keybindings into "Angband" keybindings and using those internally is braindead.
                        linux->xterm->screen->pmacs

                        Comment

                        • Sirridan
                          Knight
                          • May 2009
                          • 560

                          #42
                          Originally posted by d_m
                          Sounds like you all are already in agreement, but I agree that the client should submit [action, arg, ...] objects rather than key presses. The current Angband scheme of mapping client keybindings into "Angband" keybindings and using those internally is braindead.
                          That's what I was trying to do at first, but yeah, it was getting to be a PITA quite quick.

                          Comment

                          • Pete Mack
                            Prophet
                            • Apr 2007
                            • 6883

                            #43
                            Originally posted by d_m
                            Sounds like you all are already in agreement, but I agree that the client should submit [action, arg, ...] objects rather than key presses. The current Angband scheme of mapping client keybindings into "Angband" keybindings and using those internally is braindead.
                            This is not to say that keybindings are a bad idea per se; just that the internal model* needs one more level of redirection. Instead of switching on (original keybinding) characters, switch on command actions, and bind keys to actions rather than characters.

                            The current strict disconnect between I/O events and commands (via util.c`inkey_ex) is extremely valuable.

                            * currently implemented in dungeon.c`process_command

                            Comment

                            • Sirridan
                              Knight
                              • May 2009
                              • 560

                              #44
                              499th post... 500th will be a link to something you should like

                              Comment

                              • Sirridan
                                Knight
                                • May 2009
                                • 560

                                #45
                                Woot! 500th post!

                                Right now pyAngband has gone though some changes. I basically threw out a bunch of my object code and such, and have decided to move on with that in a simpler, ground-up approach.

                                Anyway, commands are generated client-side and sent to the game so that the core logic doesn't give half a crap about keypresses.

                                Core logic can tell the client to prompt, and can check for instant-inkey for interrupts, not that repeated commands are implemented yet...

                                Door's can be opened and closed. I need to fix prompts, but besides that it works pretty well.

                                I will upload to Github a little later, going out now. Will also post a .zip of code here since it is still quite small.

                                EDIT: Posted source as .zip, only WindowsClient.py works for now, so just run that. I'll fix and upload the CursesClient after a bit.
                                Attached Files
                                Last edited by Sirridan; November 15, 2010, 21:29.

                                Comment

                                Working...
                                😀
                                😂
                                🥰
                                😘
                                🤢
                                😎
                                😞
                                😡
                                👍
                                👎