Reusing the Angband parser

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Byrhtnoth
    Rookie
    • Mar 2017
    • 3

    Reusing the Angband parser

    Hi all,
    First off, thank you to the Angband development team for putting together such an amazing open-source project.

    I've been working on developing my own open-source game/simulator in C, relatively unrelated to Angband but storing a great deal of game information in a similar fashion (the game is essentially a fantasy city simulator, so instead of monsters or weapons it has buildings and citizens).
    While I may well end up using a language like JSON or YAML to store this data, after browsing through the Angband GitHub repo I found that the parser and data file format it uses would actually work very nicely for the kind of storage I would want, ensuring extensibility, readability and compactness.

    My question is, has anyone made an effort to let the Angband parser be used separately from Angband as its own parsing library? I've spent a fair bit of headscratching trying to figure out if I could disentangle it and port it over to another program, but I expect starting on the task would end up wasting a lot of time I'd prefer to spend working on my project's other niggly details.

    Thanks!
  • Derakon
    Prophet
    • Dec 2009
    • 8820

    #2
    I strongly encourage you to go with a standard, like JSON or XML or YAML, rather than the home-brew format that Angband uses. Standards will be easier to integrate into your system, less buggy, familiar to other people, easier to write, more portable (any system that can parse the format can read your files), etc. There is zero reason to re-use Angband's format unless you're making an Angband variant. Even then, one of the first things I did when I started working seriously on Pyrel was convert the data format into JSON.

    To answer your question, no, I am not aware of anyone who tried to extract the Angband parser out of Angband.

    Comment

    • takkaria
      Veteran
      • Apr 2007
      • 1895

      #3
      Yeah, I think you should use JSON or some other more standard format, but if you want to use the angband parser it would be pretty straightforward. It is not really that entangled with the rest of the code at all.

      Also, maybe don't write a new game in C... it's a fine language and all, but you will end up wasting half your time writing boilerplate that many other languages will give you for free.
      takkaria whispers something about options. -more-

      Comment

      • t4nk
        Swordsman
        • May 2016
        • 335

        #4
        And if you're determined to use C, I strongly recommend to consider GLib... it has a lot of very useful functionality, such as XML parser, ini parser, regular expressions, etc.

        Comment

        • Gwarl
          Administrator
          • Jan 2017
          • 986

          #5
          Sort of related, I'm working on an editor program for angband in javascript and I've written the following to parse the information from (currently) monster.txt

          [spoiler]
          Code:
          //some regex to split up the data inside the files
          //could or should be passed into this function from outside
          //some redundancy here, consolidate these expressions
          var pattern = {};
          pattern.constants = /.+?:\s.+?\n/g; 
          pattern.monster = /name:\d+:.+?\n[^]+?\n\n/g;
          pattern.newline = /.*\n/g;
          
          //lists of property and subproperty names expected from each file.
          //store these outside the program as editable JSON files
          var properties = {};
          var subproperties = {};
          //monster subproperties
          properties.monster = [
          	"name","plural","base","glyph","color","info","power","blow","flags","flags_off","spell_freq","spells","desc","drop","drop_artifact","mimic","friends","friends_base"
          ];
          subproperties.monster = {};
          subproperties.monster.name = [
          	"serial_number","monster_name"
          ];
          subproperties.monster.info = [
          	"speed","hit_points","vision","armor_class","alertness"
          ];
          subproperties.monster.power = [
          	"depth","rarity","power","scaled_power","exp_for_kill",
          ];
          subproperties.monster.blow = [
          	"attack_method","attack_effect","damage"
          ];
          subproperties.monster.drop = [
          	"tval","sval","pct_drop_chance","min","max"
          ];
          subproperties.monster.mimic = [
          	"tval","sval"
          ];
          subproperties.monster.friends = [
          	"chance","number","name"
          ];
          subproperties.monster.friends_base = [
          	"chance","number","name"
          ];
          
          //actually do the parsing
          function parsefile(filename){
          	var filedata = fs.readFileSync('./lib/gamedata/'+filename+'.txt', 'utf8');
          	var data = filedata.match(pattern[filename]);
          	var entries = [];
          	for (i=0;i<data.length;i++) {
          		//initialize the object to be read into
          		var entry = {};
          		for (value in properties[filename]) {
          			entry[properties[filename][value]]=[];
          		}
          		//parse the line in the monster entry
          		var lines = data[i].split("\n").filter(function(x){return(x!="");});
          		for (j=0;j<lines.length;j++){
          			var line=lines[j].split(":");
          			//replace '-' in property names because Javascript doesn't like it
          			var property=line.shift().replace("-","_");
          			//build the object to be the monster property
          			var property_values;
          			//handle properties with sub properties case by case
          			switch (property){
          			case "name":
          			case "info":
          			case "power":
          			case "blow":
          			case "drop":
          			case "mimic":
          			case "friends":
          			case "friends_base":
          				property_values = {};
          				for (value in subproperties[filename][property]) {
          					property_values[subproperties[filename][property][value]]=line[value];
          				}
          				break;
          			case "flags":
          			case "flags_off":
          			case "spells":
          				property_values=line.join(" ").split("|").join(" ");
          				break;
          			case "desc":
          			default:
          				property_values=line.join("");
          				break;
          			}
          			//hack to cope with multiple lines because initialization didn't work
          			if (typeof entry[property]=='undefined') entry[property]=[];
          			entry[property].push(property_values);
          		}
          		//hack the hack
          		for (j=0;j<properties[filename].length;j++) {
          			if (typeof entry[properties[filename][j]]=='undefined') entry[properties[filename][j]]=[];
          		}
          		//add our finished object to the list
          		entries.push(entry);
          	}	
          	return entries;
          }
          [/spoiler]

          Comment

          • Byrhtnoth
            Rookie
            • Mar 2017
            • 3

            #6
            Thanks for the comments, guys. I've decided to go ahead and use JSON to store everything rather than contort myself. Derakon, you make a good point about familiarity and portability.

            I'll admit, C seems like a rather insane choice; I mostly wanted to challenge myself and review my C experience from my undergrad CS courses. I may end up switching to a more OOP-friendly language if I decide it's not worth reimplementing things as takkaria referenced.

            Comment

            • Pete Mack
              Prophet
              • Apr 2007
              • 6697

              #7
              C++ is probably better. virtual methods are rather less of a pain then a bunch of arrays of function pointers. (And no, angband didn't used to work that way--which was a serious oversight, IMO.)

              One problem in C is absolutely everything needs to be hand written if you want portability--even events and menus. Yes it was fun to do...once.

              Comment

              • AnonymousHero
                Veteran
                • Jun 2007
                • 1322

                #8
                If this is long term project, PLEASE don't do this in C or C++. If it is and it really does require "soft real-time" then do it in Rust. Otherwise, choose the thing you know... unless it's a learning experience, in which case choose a high-level GC'd language. There are multiple choices in that space depending on how comfortable you are with types... you can go LISPish with Racket or 'intermediate' with O'Caml and go type-nuts with Haskell/GHCJS.

                Please ask if you're not sure about any of those options. I have a lot of hard-won experience. (As I'm sure many others on this forum have.)

                Comment

                • AnonymousHero
                  Veteran
                  • Jun 2007
                  • 1322

                  #9
                  Originally posted by Pete Mack
                  C++ is probably better. virtual methods are rather less of a pain then a bunch of arrays of function pointers. (And no, angband didn't used to work that way--which was a serious oversight, IMO.)

                  One problem in C is absolutely everything needs to be hand written if you want portability--even events and menus. Yes it was fun to do...once.
                  Heh, I feel you, man.

                  I don't mind the hand-coding of menus, but having to hand-code N versions of lists-of-various things, etc. just kills me.

                  Comment

                  • Byrhtnoth
                    Rookie
                    • Mar 2017
                    • 3

                    #10
                    Thanks for the suggestions guys! Really supportive atmosphere here.

                    As a matter of fact, I went and looked at C++ right after the first few responses, and then looked around some more when I grasped how huge the language is. I've mostly programmed in Python, Java and C in the past, with some experimentation in Racket, JS and C#. I don't really want to deal with Java's verbosity much, and I felt like using something other than Python this time around.
                    In the interest of exploration I went and started reading through the Rust docs (loving the language so far -- all my favourite features of C, Racket and Python are present!) I'm glad to hear you recommend it, AnonymousHero!

                    The project likely doesn't require Rust's safety or concurrency features (although they could come in handy if I wanted to get very fancy with it). Nonetheless, I'd certainly like it to be long-term and running with a low performance overhead (ideally a compiled language, though it makes less of a difference nowadays), and I quite like Rust's style (and package manager!) If I feel like I'd rather stick to something a bit more familiar, I'll probably use C# or Racket.

                    Comment

                    • t4nk
                      Swordsman
                      • May 2016
                      • 335

                      #11
                      All this talk about how horrible C is made me want to start hacking on Angband again C is fun. Let's try to compile this thing... heh, it works. Thanks, Nick!
                      Let me think... ientification, traps, curses and other annoying things should be removed, combat system rewritten... ok, I don't want to derail this thread

                      Comment

                      • Pete Mack
                        Prophet
                        • Apr 2007
                        • 6697

                        #12
                        Well yes. That's why I wrote the menu system.
                        Originally posted by AnonymousHero
                        Heh, I feel you, man.
                        I don't mind the hand-coding of menus, but having to hand-code N versions of lists-of-various things, etc. just kills me.

                        Comment

                        • Pete Mack
                          Prophet
                          • Apr 2007
                          • 6697

                          #13
                          C# is a reasonably nice language, but it's not fully portable. Mono is always a bit behind. Python drives me crazy, because of its runtime type check. Very painful on a large project, though apparently this is solved to some extent by more recent versions.

                          Originally posted by Byrhtnoth
                          Thanks for the suggestions guys! Really supportive atmosphere here.

                          As a matter of fact, I went and looked at C++ right after the first few responses, and then looked around some more when I grasped how huge the language is. I've mostly programmed in Python, Java and C in the past, with some experimentation in Racket, JS and C#. I don't really want to deal with Java's verbosity much, and I felt like using something other than Python this time around.
                          In the interest of exploration I went and started reading through the Rust docs (loving the language so far -- all my favourite features of C, Racket and Python are present!) I'm glad to hear you recommend it, AnonymousHero!

                          The project likely doesn't require Rust's safety or concurrency features (although they could come in handy if I wanted to get very fancy with it). Nonetheless, I'd certainly like it to be long-term and running with a low performance overhead (ideally a compiled language, though it makes less of a difference nowadays), and I quite like Rust's style (and package manager!) If I feel like I'd rather stick to something a bit more familiar, I'll probably use C# or Racket.

                          Comment

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