in reply to RFC: RPG ;-)

Is Tk a given? It is ok, but doesn't (last time I checked) run natively on a Mac. Wx works well on Macs, windows and Linux. I'm not sure about other options, but there has been lots of talk around here about choosing a GUI library. Whatever GUI you decide on, make sure you are not tightly coupled to it. You may learn to hate your choice. If your design relies on it, you will be stuck with it.

When designing your data structures, I would pick at least two very different games (GURPs vs 1st Edition AD&D) as test cases. If the abstractions can handle very different systems easily, then you know you are on the right track.

For data persistence, look at DBD::SQLite and DBM::Deep. YAML::XS is very nice for quick storage and retrieval of data structures.

If you decide to go OOP with your software, you will either want to drink to Kool-Aid and use Moose, or use classical perl hash-based objects. Pick one. In any case, if you choose OOP, remember that 9 out of 10 times composition is a better strategy than inheritance.

This sounds like a big project. Break it into tiny pieces with usable deliverables. That way you can start benefiting from it quickly, and you will stay interested. Plus you will be more likely to get others interested as well.

From the start, plan on using something like PAR::Packer to make bundled executables for the Perl challenged. You will increase your chances of getting users.

Most important: have fun.


TGI says moo

Replies are listed 'Best First'.
Re^2: RFC: RPG ;-)
by pobocks (Chaplain) on Nov 06, 2008 at 05:43 UTC

    Thank you! Very helpful.

    TK isn't a given in terms of being installed on Macs, but it does work on them. Plus, it's the GUI toolkit that I know anything about ;-) I have a tendency to flit between technologies... a little bit of lisp, some javascript, some PHP, etc. Part of this is about forcing myself to gain some depth.

    When designing your data structures, I would pick at least two very different games (GURPs vs 1st Edition AD&D) as test cases. If the abstractions can handle very different systems easily, then you know you are on the right track.

    Exactly my plan. I'm going to test it with D&D 3.5, oldskool White Wolf, and Paranoia.

    As far as data persistance goes... What little I have of a workflow planned out is based on the idea that you load up (or create) a game, and it reads it off disk and keeps it in memory until it gets saved. Seems like a better fit for a JSON, YAML, XML, etc type solution than for SQLite. (Also, my experience with Amarok and SQLite makes me a bit unreasonably squeamish about it.). I'll definitely check out YAML::XS.

    I'll check out Moose, but I should be able to manage this with little more than Perl's built in data types... I definitely agree on the "Composition over inheritance;" as far as I can tell, inheritance is something that is useful in either in radical redesign or in adapting someone else's code in a hurry.

    I definitely want to... Do you have any suggestions for a logical first deliverable? I mean, I guess maybe a character-sheet creator would be the first step... but maybe that's too big. I'ma scared! ;-)

    Thanks SO much for the PAR::Packer suggestion. I've done some things with Perl2exe, but until I have more cash flow than I do at the moment, that's not an option for anything to be distributed more widely.

    for(split(" ","tsuJ rehtonA lreP rekcaH")){print reverse . " "}print "\b.\n";

      I tend to use oop if I am working with deep data structures. It makes my life much easier.

      Instead of having to remember that I've got a hash of arrays of hashes with arrays under key Foo and hashes under Bar. Its easier for me to think of I have an array of Characters, each character has a set of Attributes.

      Inheritance is a way reuse code. If I need to model Apple, Banana, and Orange in my code, I can create a Fruit base class that defines common attributes and interfaces for all of the fruit types. Fruit would provide "weight", "color", "stem", "remove_peel" and "eat" methods. Each fruit would inherit the "weight" method, since it would be the same for all of them. "Apple" may be able to inherit "eat", but "Banana" and "Orange" would override "eat" to check that the peel has been removed first. "Banana" would need to add a "remove_nast_black_thing_from_the_end" method, and make sure that it gets called as part of the "eat" method as well. This example works well because an Apple is really a Fruit. As is an Orange and a Banana.

      The comments about inheritance are important. People do stupid things like, my "Apple" object has a bunch of stuff that is much like what I want my "Orange" object to do. So, If I make "Orange" a subclass of "Apple" I can reuse my code and that is good. Another misuse of inheritance would be to say that an "Office" object is a "Person" so that you can call the Person methods and get the name of the person assigned to the office. The right way to do this is to say that an Office 'has a' Person, in other words, use composition, not inheritance. Office could then define an "assigned_to" method, to fetch the name of its Person.

      Read some tutorials on OOP, and Damian Conway's Object Oriented Perl book also provides some excellect information. OO design is a bit tricky at first, but it is a worthwhile skill to build.

      If you want to print from your program, WxPerl has an easy to use cross platform printing interface (but it depends on using WxPerl for your UI). You may also wish to look at Win32::Printer, I haven't used it, so I can't really comment on it. Another option would be to punt and generate PDF files.

      One thing that annoyed me when I was gaming a lot, was copying and recopying character sheets, as spills or eraser wear destroyed old copies. A nice character sheet printer would be very handy. Printing nice blank sheets would be a nice bonus.

      I think that you will eventually want to have search capabilities. That's where an SQL type db comes in really handy. I've never had any problems with SQLite, even with very large files (hundreds of MB). I don't know what the problems were with Amarok, so I can't comment about that. If you go with an embedded SQL datastore, you may want to look at some of the ORM opptions, like Class::DBI or Rose::DB. My best advice is to keep you serialization and deserialization code isolated from everything else, so that you can change or add different data stores easily.


      TGI says moo

        I'll check out wxPerl, but I'm pretty set on Tk.

        The SQLite problems were pretty simple performance over large datasets problems. Basically, tried to use an SQLite backend on Amarok with over 4000 songs, and it would freeze and fail. Switched to a MySQL backend, and voila, Amarok runs great. Probably there will be much less data to deal with here, but I'd rather find something that I know will scale reasonably from the start.

        for(split(" ","tsuJ rehtonA lreP rekcaH")){print reverse . " "}print "\b.\n";