Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old November 14, 2016, 17:11   #11
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 4,046
Donated: $40
Pete Mack is on a distinguished road
In Python (like other languages with first class types) the compiler is part of the language. The same holds for C#, Java, Haskell. This is a natural way to do these things, unlike the hideous days of Lua, which really was the worst of both worlds.

In the mean time, adding to .h files is much, much less of a chore than actually writing code. As far as I know, the only remaining hard-coded stuff is for elemental resistance, where side effects, vulnerability, and immunity, make things more complicated than the .h file encodes for.
Pete Mack is offline   Reply With Quote
Old November 14, 2016, 19:49   #12
Nick
Vanilla maintainer
 
Nick's Avatar
 
Join Date: Apr 2007
Location: Canberra, Australia
Age: 52
Posts: 6,524
Donated: $60
Nick is on a distinguished road
Quote:
Originally Posted by Derakon View Post
The code that parsed these files would hand off the "use_effect" section to a separate parser, which would examine the "proc_type" entry to determine which function to call, and then hand that function the rest of the entry (with the radius, target info, element, and damage) which it would use as parameters to decide what to actually do. So somewhere in the code was a mapping of strings to functions that looked like this:
Code:
PROC_TYPES = {
  "ball": proc_ball_func,
  "beam": proc_beam_func,
  "all_los": proc_hit_everything_func,
  ...
}
All of those functions had the same signature: they took a "record" parameter, which is one of the mappings loaded from the data file. They were then responsible for extracting data from the record, providing default values for anything that wasn't present, etc.
Right, and this is very similar to how the effect code currently behaves, except that there's an entry like this in the wand template in object.txt:
Code:
effect:BALL:COLD:2
dice:100
, a list of effect templates like this in list-effects.h:
Code:
EFFECT(BALL, true, "dam",	3, EFINFO_BALL, "fires a ball of %s with radius %d, dealing %s damage at the centre")
and then the array of effect handlers is set up like this in effects.c:
Code:
static const struct effect_kind effects[] =
{
	{ EF_NONE, false, NULL, NULL, NULL },
	#define F(x) effect_handler_##x
	#define EFFECT(x, a, b, c, d, e)	{ EF_##x, a, b, F(x), e },
	#include "list-effects.h"
	#undef EFFECT
	#undef F
	{ EF_MAX, false, NULL, NULL, NULL }
};
In the case of effects, this probably has the info pushed out almost far as possible, with anything the user will really want to edit in object.txt (arguably the string in list-effects.h should be in a text file too - in particular if we're looking at ease of translating the game - but that wasn't really part of the question).

The question I was asking (and which you answered in your first reply) was whether to use #defines and stringification, or direct association like your PROC_TYPES array, or some third thing.
__________________
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them.
Nick is online now   Reply With Quote
Old November 14, 2016, 21:37   #13
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,285
AnonymousHero is on a distinguished road
Quote:
Originally Posted by Derakon View Post
Note that the solution I came up with for Pyrel for this problem did not involve embedding code into the data files, even though I could have trivially done that as Python has an exec() function that allows it to execute strings as programs*. Instead, if I wanted e.g. a wand that fired three elemental balls in succession, then the wand's object file entry would look something like:
Right, the tricky part in this scheme is coming up with a suitable "algebra" for combining spells/effects/etc without accidentally ending up with a TC language. (And spells are one thing, effects of wearing items another.)

Even still, this only gets you so far: You don't really get much in the way of being able to mod entirely new flags, say, without an embedded language. (But as I say, I'm not sure it's worth the effort. The ToME2/old Angband way definitely wasn't.)

Last edited by AnonymousHero; November 14, 2016 at 21:47.
AnonymousHero is offline   Reply With Quote
Old November 14, 2016, 21:45   #14
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,285
AnonymousHero is on a distinguished road
Quote:
Originally Posted by Pete Mack View Post
In Python (like other languages with first class types) the compiler is part of the language. The same holds for C#, Java, Haskell. This is a natural way to do these things, unlike the hideous days of Lua, which really was the worst of both worlds.
Nope, not for (at least) Java nor Haskell. There's no guarantee that a running problem will have access to the compiler in either of those languages. (After all, the JDK is separate from the JRE. You only need the JRE to run Java bytecode. However, it is possible to generate bytecode at runtime and to use that. Can't recall if something similar might be possible with the GHC Haskell interpreter, but definitely not in general Haskell code. It's possible to load (compiled) code at runtime, though.)

Quote:
Originally Posted by Pete Mack View Post
In the mean time, adding to .h files is much, much less of a chore than actually writing code. As far as I know, the only remaining hard-coded stuff is for elemental resistance, where side effects, vulnerability, and immunity, make things more complicated than the .h file encodes for.
I think the point here is that if you use e.g. a LISP (i.e. good for DSLs), it would be entirely possible to keep the data files just as succinct as they are now while also allowing things like changing how e.g. BLINK i monster.txt functions. (Spell effects are mostly hardcoded; see e.g. CAUSE_1, CAUSE_2, etc.)
AnonymousHero is offline   Reply With Quote
Old November 14, 2016, 22:07   #15
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 7,883
Derakon is on a distinguished road
Quote:
Originally Posted by AnonymousHero View Post
Right, the tricky part in this scheme is coming up with a suitable "algebra" for combining spells/effects/etc without accidentally ending up with a TC language. (And spells are one thing, effects of wearing items another.)

Even still, this only gets you so far: You don't really get much in the way of being able to mod entirely new flags, say, without an embedded language. (But as I say, I'm not sure it's worth the effort. The ToME2/old Angband way definitely wasn't.)
Given my experience with Pyrel and trying to make a fully-general equipment/stats/spells system, it's not worth the complexity of implementation. I would definitely stick to trying to support the current use case only, at least as far as data files are concerned. We want to make it easy to add new behaviors, but really mostly only in that we have a big glowing sign in the source code that says "ADD NEW BEHAVIORS HERE". Ideally the dev creates a function, declares a string for it, adds the string/function pair to a mapping somewhere, and then starts using the new behavior in the data files.
Derakon is offline   Reply With Quote
Old November 14, 2016, 22:16   #16
Pete Mack
Prophet
 
Join Date: Apr 2007
Location: Seattle, WA
Posts: 4,046
Donated: $40
Pete Mack is on a distinguished road
Well sure you have to load the jdk as a jar file in order to use it, just like any other library. The same holds for haskell and C#. But it's perfectly feasible--much easier than in C/C++, where dynamic calls are a huge pain in the neck, never mind needing installed .h files and compiler for it to "work" at all.

Quote:
Originally Posted by AnonymousHero View Post
Nope, not for (at least) Java nor Haskell. There's no guarantee that a running problem will have access to the compiler in either of those languages. (After all, the JDK is separate from the JRE. You only need the JRE to run Java bytecode. However, it is possible to generate bytecode at runtime and to use that. Can't recall if something similar might be possible with the GHC Haskell interpreter, but definitely not in general Haskell code. It's possible to load (compiled) code at runtime, though.)



I think the point here is that if you use e.g. a LISP (i.e. good for DSLs), it would be entirely possible to keep the data files just as succinct as they are now while also allowing things like changing how e.g. BLINK i monster.txt functions. (Spell effects are mostly hardcoded; see e.g. CAUSE_1, CAUSE_2, etc.)
Pete Mack is offline   Reply With Quote
Old November 15, 2016, 06:35   #17
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,285
AnonymousHero is on a distinguished road
Quote:
Originally Posted by Pete Mack View Post
Well sure you have to load the jdk as a jar file in order to use it, just like any other library.
I don't believe that it's specified anywhere in the standards that this needs to be possible. It may be possible currently if you're using the "right" JRE/JDK, but it's hard enough to get non-developer users to install the JRE, so in practice it's not really going to be workable unless you control the deployment environment (which Angband does not). Plus, most code requires a metric ton of dependencies which is going to be fun for users to download. (The "download the internet" phrase is only funny if you're on a fast internet connection.)

... and, actually, I don't I've seen a single example of this being done in practice (other than development tools, possibly) of over 10+ years of Java development. Do you have any examples?

Quote:
Originally Posted by Pete Mack View Post
The same holds for haskell and C#.
Haskell is a language not a compiler. I think you mean GHC Haskell. Can't comment on C# as I don't know enough about it.

Quote:
Originally Posted by Pete Mack View Post
But it's perfectly feasible--much easier than in C/C++, where dynamic calls are a huge pain in the neck, never mind needing installed .h files and compiler for it to "work" at all.
No argument that it's a huge pain in C++ (because of name mangling, etc.), but things like https://github.com/vgvassilev/cling already exist.

In the GHC Haskell case, unless you're using only the "base" set of packages (which ship with GHC and are always installed) then it's going to be a huge pain too. Just try using e.g. xmonad or yi or propeller from a sandbox[1] and you'll see what I mean. (At least this was the case ~3-12 months ago.)

[1] To avoid having to install packages "globally". Perhaps nix-style builds will eventually get around this problem, but it's still a bit unstable.

Last edited by AnonymousHero; November 15, 2016 at 06:49.
AnonymousHero is offline   Reply With Quote
Old November 15, 2016, 06:43   #18
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,285
AnonymousHero is on a distinguished road
Quote:
Originally Posted by Derakon View Post
Given my experience with Pyrel and trying to make a fully-general equipment/stats/spells system, it's not worth the complexity of implementation. I would definitely stick to trying to support the current use case only, at least as far as data files are concerned. We want to make it easy to add new behaviors, but really mostly only in that we have a big glowing sign in the source code that says "ADD NEW BEHAVIORS HERE". Ideally the dev creates a function, declares a string for it, adds the string/function pair to a mapping somewhere, and then starts using the new behavior in the data files.
Agreed -- unless someone can come up with a good composable way (i.e. an "algebra of spell effects") to generalize.

I do think the situation with the X macros could be improved a little bit[1] with a small custom code generator instead, but it's likely to be a small improvement.

Anyway, I think this this topic's been more or less exhausted, so I'll leave it at that .

[1] X macros get a bit unwieldly editing-wise and rather error prone if you need to remove columns (or insert columns in the middle). They're also a bit annoying if you need to derive other compile-time data from them (e.g. the classic MAX_* macros).
AnonymousHero is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Ladder data in excel or calc eugensk00 Oook! 0 January 2, 2015 12:32
RST help files fph Development 13 September 6, 2011 20:08
delete.me files konijn_ Development 2 December 8, 2009 22:43
edit files? tummychow Vanilla 2 September 13, 2009 20:38
How about ... replacing /edit/*.txt and /data/*.raw with SQLite ? PaulBlay Development 22 June 8, 2009 03:31


All times are GMT +1. The time now is 22:57.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2017, vBulletin Solutions, Inc.