Pyrel dev log, part 2

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Derakon
    Prophet
    • Dec 2009
    • 9022

    Okay, I've emailed wxpython-users; we'll see what they have to say about it.

    EDIT: okay, problem solved. The automatic resizing I mentioned apparently only goes one "layer" deep -- a Panel in a Frame will resize automatically, but the contents of that Panel will not. The solution is to stick the TextCtrl inside a Sizer and set the Sizer on the Panel. Try changing the constructor for the MessageFrame to this:
    Code:
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, title = "Message history")
            panel = wx.Panel(self)
            sizer = wx.BoxSizer()
            self.text = wx.TextCtrl(panel, style = wx.TE_MULTILINE)
            sizer.Add(self.text, 1, wx.EXPAND)
            panel.SetSizer(sizer)
    Last edited by Derakon; August 30, 2012, 23:05.

    Comment

    • ekolis
      Knight
      • Apr 2007
      • 921

      Yay, that fixed it - thanks! (Though you can still type in the message window! :P)

      ...Wait, you can call SetSizer on a panel? I thought it only worked on Frame objects, so I was jumping through all sorts of hoops to make the sizing work!

      Oh, and did you know that you can access the properties C#-style, not just Java-style? E.g. instead of

      panel.SetSizer(sizer)

      you can just say

      panel.Sizer = sizer

      You read the scroll labeled NOBIMUS UPSCOTI...
      You are surrounded by a stasis field!
      The tengu tries to teleport, but fails!

      Comment

      • Derakon
        Prophet
        • Dec 2009
        • 9022

        Originally posted by ekolis
        Yay, that fixed it - thanks! (Though you can still type in the message window! :P)
        That's what we get for using a TextCtrl for the message window. Personally, I'm fine with it -- I imagine eventually the message log could include player notes simply by the player typing what they want to note down into that window.

        Oh, and did you know that you can access the properties C#-style, not just Java-style? E.g. instead of

        panel.SetSizer(sizer)

        you can just say

        panel.Sizer = sizer
        I didn't know that...but I'd rather use the getters/setters, as a matter of style. And on that note, I should write a Pyrel style guide at some point.

        Comment

        • Derakon
          Prophet
          • Dec 2009
          • 9022

          Continuing from the previous post, I've written up a quick style guide for editing Pyrel. This, in combination with PEP8, more or less describes how Pyrel is currently written; if we want to change the rules, then we should go through the current codebase and change them to match as well. Fortunately said codebase is still small enough that that would be feasible (if tedious), so now's the time to disagree with my personal coding style.

          Next step: mtadd's pull request, then ekolis's.

          Comment

          • ekolis
            Knight
            • Apr 2007
            • 921

            What makes you think that spaces will make people happier than tabs?

            Reasons to use spaces:
            * They don't do any magic voodoo with one character taking up multiple spots in a text file display
            * Open-source folks seem to like them, for some strange reason

            Reasons to use tabs:
            * They are easy to manipulate - just one tab/backspace indents/unindents! (As opposed to typing four spaces to indent and four backspaces to unindent, or one tab to make four spaces to indent and four backspaces to unindent, or trying to find some obscure editor plugin that converts between tabs and spaces)
            * If you prefer a different amount of indentation than four spaces, just adjust your editor preferences - no need to break everyone else's code or force everyone to the One True Indent Size (tm)
            * They save a few bytes per line on file size (OK, this one's pretty trivial, but hey, I gotta come up with a third reason so tabs have more reasons than spaces! Hey, I like tabs! )
            You read the scroll labeled NOBIMUS UPSCOTI...
            You are surrounded by a stasis field!
            The tengu tries to teleport, but fails!

            Comment

            • ekolis
              Knight
              • Apr 2007
              • 921

              By the way, your example of "mixedCase" not "CamelCase" is incorrect - the former is actually called camel-case! (Not sure what the latter is called - maybe "capitalize each word"?)
              You read the scroll labeled NOBIMUS UPSCOTI...
              You are surrounded by a stasis field!
              The tengu tries to teleport, but fails!

              Comment

              • Derakon
                Prophet
                • Dec 2009
                • 9022

                Spaces vs. tabs is non-negotiable; I'm putting my foot down on that one, largely because the space-vs.-tabs debate is legendarily impossible to resolve and I don't want to get into a huge argument about it. Yes, there's good reasons to use both. Pyrel happens to use spaces. The absolute worst thing you can do in this debate is to have a project that mixes them. Thus, use spaces.

                In any event, a smart editor will not require you to hit delete four times to eliminate four spaces, and will automatically start a new line at the appropriate level of indentation. They'll also typically make it easier to recognize when you've accidentally used a tab so you can fix it. If you don't already know how, I suggest learning to use vim or emacs.

                EDIT: as for CamelCase vs. mixedCase vs. whatever, I've seen differing opinions on what exactly to call them (Wikipedia mentions "headlessCamelCase", for example, implying that there's a "HeadedCamelCase" or something). The terms I used are the ones used by PEP8, which seems an adequate justification.

                Comment

                • Derakon
                  Prophet
                  • Dec 2009
                  • 9022

                  Okay, mtadd's pull request is in! Thanks for your help! Command execution is now handled by coroutines instead of threading; a similar premise in that each Command gets its own execution context, but there's no concern about exactly what order code is executed in, no need to strew locks about the place, all that nasty stuff you usually buy into when you add threading.

                  ekolis, I'll get to your pull request tomorrow. Sorry for the delay; I was busier today than I anticipated.

                  Comment

                  • Derakon
                    Prophet
                    • Dec 2009
                    • 9022

                    Off the top of my head, some things that need doing:

                    1) Port over some utility functions. Specifically here I'm thinking about the projection code (for firing projectiles, determining LOS, etc.).

                    2) Implement LOS, and a knowledge system (e.g. casting a detection spell gives the player knowledge of certain Things for a certain duration of time). Allow the game to lie to the player ("so far as you know, that door's still closed").

                    3) Implement container Things, mostly for spellbooks and quivers*

                    4) Add animation support. There's a number of ways I could do this. One would be to have animations be Things whose energy-gain rate is negative; the engine would interpret this as "arbitrarily high" with a side-order of "redraw the game every time one of these is updated". That's pretty hacky though, so an alternate system would be to have them be their own thing that's implemented similarly to a Prompt -- that is, as an overlay on the normal game display. The main issue is figuring out what bits belong engine-side and what bits belong UI-side. I mean, should we enforce that animations are caused by an entity rapidly moving from one tile to another? What if we want to have a "professional" UI with smooth motion between tiles, arcing shots, particle explosions, etc?

                    5) Just a bit of refactoring -- the entire game should belong inside a "pyrel" namespace. This will wreak a bit of havoc with the repo's file history (since every file in the repo will need to be moved) but is not otherwise difficult and should be done sooner rather than later. I'm waiting on ekolis to respond to my comments on his pull request; once that's done, I'll do this change just to get it over with.

                    * Current theory: a quiver is an item that you can put ammo into. Each quiver can hold up to 40 ammo units. Wielding a quiver allows you to fire its ammo, possibly with a slight speed advantage compared to firing out of the pack (should the player be allowed to fire out of quivers in the pack? Probably not...). Quivers could be enchanted to protect their contents, but probably not have any other enhancements.

                    Comment

                    • Magnate
                      Angband Devteam member
                      • May 2007
                      • 5110

                      Originally posted by Derakon
                      Off the top of my head, some things that need doing:

                      1) Port over some utility functions. Specifically here I'm thinking about the projection code (for firing projectiles, determining LOS, etc.).
                      My Python isn't good enough to do this, but I put a lot of thought into how to improve V's projection code to make it more flexible and useful, and I'd very much welcome a chance to input into this. Alternatively I could just roll my sleeves up and get started with your guidance, which effectively nukes any chance of me going back to v4! (EDIT: it occurs to me that you need a LOS function *before* doing projection - though of course it doesn't have to be your final LOS function straight off.)
                      4) Add animation support. There's a number of ways I could do this.
                      Forgive me if this is terribly noob-ish, but it seems to me that animations, as a display feature, should *all* be firmly on the UI side. The engine basically says "this thing moves here" or "this thing explodes" or whatever, and the UI looks at its current display options and decides whether and how to animate each of those instructions.
                      * Current theory: a quiver is an item that you can put ammo into. Each quiver can hold up to 40 ammo units. Wielding a quiver allows you to fire its ammo, possibly with a slight speed advantage compared to firing out of the pack (should the player be allowed to fire out of quivers in the pack? Probably not...). Quivers could be enchanted to protect their contents, but probably not have any other enhancements.
                      How keen are you to retain flexibility within the game engine to implement different game rules? I'm a big believer in this, so would urge you to make whether or not Things can be used directly from Containers (or nested Containers of the same or different sorts) something that is easily configurable. Ditto rules like what containers can fit inside others etc.

                      So for example, let's say that each Container object has a property called canFire, which means that objects inside it can be immediately extracted and fired/thrown/etc. You could then define that property in object.txt for each container object. In fact it needn't be boolean, it could be an amount of energy used to extract the object and ready it for use. So a quiver might required only 5 energy for the extraction of an arrow, while a backpack might require 15 (and a quiver inside a backpack 20, etc.). Possibly too complicated, of course.

                      I'll stop rambling now.
                      "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

                      Comment

                      • Derakon
                        Prophet
                        • Dec 2009
                        • 9022

                        Originally posted by Magnate
                        My Python isn't good enough to do this, but I put a lot of thought into how to improve V's projection code to make it more flexible and useful, and I'd very much welcome a chance to input into this. Alternatively I could just roll my sleeves up and get started with your guidance, which effectively nukes any chance of me going back to v4! (EDIT: it occurs to me that you need a LOS function *before* doing projection - though of course it doesn't have to be your final LOS function straight off.)
                        I kind of assumed that LOS would be handled by the projection function -- project to all tiles adjacent to the player, then project to the tiles adjacent to those tiles, stopping any time a tile is not "seeable". Perhaps that's inefficient though.

                        A couple weeks ago I made an abortive attempt at writing a heat map for pathfinding, which made me realize that one thing Pyrel really needs is a way to pull out the actual obstructions in the map as a 2D array. Its current property-map approach to storing objects works very well when you want to find everything that matches X criterion and then do some simple filtering (e.g. all creatures that are evil, all items in a given tile), but doesn't work well for area-based operations.

                        Forgive me if this is terribly noob-ish, but it seems to me that animations, as a display feature, should *all* be firmly on the UI side. The engine basically says "this thing moves here" or "this thing explodes" or whatever, and the UI looks at its current display options and decides whether and how to animate each of those instructions.
                        Yes, you're right. What this probably means is that each UI layer must implement a set of animation routines (including "move this object through these tiles", "create an explosion of radius N at this location", etc.). The main problem is that we do need for animations to trace the projection path (taking appropriate hockey-sticks as they go) so the player knows what happens. But that should be solvable.

                        How keen are you to retain flexibility within the game engine to implement different game rules? I'm a big believer in this, so would urge you to make whether or not Things can be used directly from Containers (or nested Containers of the same or different sorts) something that is easily configurable. Ditto rules like what containers can fit inside others etc.

                        So for example, let's say that each Container object has a property called canFire, which means that objects inside it can be immediately extracted and fired/thrown/etc. You could then define that property in object.txt for each container object. In fact it needn't be boolean, it could be an amount of energy used to extract the object and ready it for use. So a quiver might required only 5 energy for the extraction of an arrow, while a backpack might require 15 (and a quiver inside a backpack 20, etc.). Possibly too complicated, of course.
                        Basically all of those bullet items I mentioned previously should get their own proper "how should this be designed" post. I was just making a to-do list, not fully-detailing how things should be done. Of course flexibility in interacting with containers is valuable, and having variable energy costs for those interactions isn't a bad idea -- though we need to be careful about what to do if the energy cost exceeds 100. This is another area where having a good way of displaying the time cost of actions would be helpful.

                        Comment

                        • Magnate
                          Angband Devteam member
                          • May 2007
                          • 5110

                          Originally posted by Derakon
                          I kind of assumed that LOS would be handled by the projection function -- project to all tiles adjacent to the player, then project to the tiles adjacent to those tiles, stopping any time a tile is not "seeable". Perhaps that's inefficient though.
                          No, we're just at cross-purposes. When I said you need LOS before doing projection, I meant you need a function that returns see-able-ness of a grid. You are right that the projection function processes all tiles within the area of effect and acts upon them accordingly (according to whether it's projecting a bolt, beam, cone, ball etc. etc.).
                          Of course flexibility in interacting with containers is valuable, and having variable energy costs for those interactions isn't a bad idea -- though we need to be careful about what to do if the energy cost exceeds 100. This is another area where having a good way of displaying the time cost of actions would be helpful.
                          I think we could do much more with variable energy costs for all sorts of things, not just fractional blows / casting like we have now. A one-screen table of energy costs would be nice and straightforward for players to understand.

                          100 is an arbitrary number (and you've gone decimal anyway, yes?) - the two key concepts are:

                          1. There is an energy threshold below which you do not get to take a turn yet

                          and

                          2. There is a maximum amount of energy you may expend in a single turn's action(s).

                          Not sure how those fit into your decimal speed system described in a previous post ...
                          "Been away so long I hardly knew the place, gee it's good to be back home" - The Beatles

                          Comment

                          • mtadd
                            Rookie
                            • Nov 2011
                            • 24

                            My Python isn't good enough to do this, but I put a lot of thought into how to improve V's projection code to make it more flexible and useful, and I'd very much welcome a chance to input into this. Alternatively I could just roll my sleeves up and get started with your guidance, which effectively nukes any chance of me going back to v4! (EDIT: it occurs to me that you need a LOS function *before* doing projection - though of course it doesn't have to be your final LOS function straight off.)
                            Rogue Basin has a a good article on FOV using recursive shadowcasting with a python implementation.

                            Comment

                            • ekolis
                              Knight
                              • Apr 2007
                              • 921

                              Originally posted by Derakon
                              I kind of assumed that LOS would be handled by the projection function -- project to all tiles adjacent to the player, then project to the tiles adjacent to those tiles, stopping any time a tile is not "seeable". Perhaps that's inefficient though.
                              Wouldn't that let you see around corners?
                              You read the scroll labeled NOBIMUS UPSCOTI...
                              You are surrounded by a stasis field!
                              The tengu tries to teleport, but fails!

                              Comment

                              • Derakon
                                Prophet
                                • Dec 2009
                                • 9022

                                Originally posted by ekolis
                                Wouldn't that let you see around corners?
                                No; you wouldn't be projecting from the tile to its adjacent tiles, but from the adjacent tiles to the player. Basically you're floodfilling out from the player to find all visible tiles, with the assumption being that if a tile is not adjacent to a visible tile then it is not itself visible.

                                But I'll check out that shadowcasting approach. Why bother re-inventing the wheel? Thanks, mtadd!

                                Comment

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