I7: Implementing Trainable Skills

3 views
Skip to first unread message

Matt

unread,
Feb 17, 2010, 10:17:58 PM2/17/10
to
Hi, I'm working on a new extension and have no idea where to begin!
About a year ago, I made a rather clunky extension for combat; I've
since made some improvements, but it's still rather awkward and breaks
the "flow," so to speak, of a good game. (It's based on numbers and
randomness and ... yeah, not good.)

My goal is to create two completely new extensions. The first one will
be to implement skills into a game. For example, the player might have
the skill of swimming. These skills are learnable (as in, they must be
learned before they can be used, unless they know them already at the
beginning of the game) and trainable (as in, once the player has
learned a skill, they can perform a certain action to get better at
it.) The idea is that, using the swimming example, the player might
learn how to swim by talking to an instructor, then go swim in a lake
or something for a few turns to get better at it. The better they get,
the longer/further/etc. they will be able to swim ... so then after
training for awhile, they might be able to swim the ocean! :D

(Oh, in case you're interested, the second one will eventually include
a bunch of combat-related skills and some other goodies, like auto-
corpses. But that's not really relevant.)

I haven't done any Inform programming for quite some time, so my
syntax is more than a bit rusty, but so far I have defined skills as a
kind of thing and given them a state of being either learned or
unlearned. I'm just unsure about 1) how I should set up the whole
learning action to make it as seamless as possible, and 2) how
different levels of skill proficiency would even be implemented. I do
know that I want to stay away from numbers as much as possible ... for
preference, there would be text states describing skill levels.

Any help, guys? Maybe some sample code you could send my way to work
from? That would help a lot!!


~Matt

Erik Temple

unread,
Feb 18, 2010, 10:43:13 AM2/18/10
to
On Feb 17, 9:17 pm, Matt <jedima...@gmail.com> wrote:
> I haven't done any Inform programming for quite some time, so my
> syntax is more than a bit rusty, but so far I have defined skills as a
> kind of thing and given them a state of being either learned or
> unlearned. I'm just unsure about
>
> 1) how I should set up the whole
> learning action to make it as seamless as possible, and

From what you've said, I don't think that you really need a learning
action. Of course, that depends on how you see this working in terms
of how much the extension does and how much individual authors are
expected to do; this wasn't very clear in your original post. I would
probably simply set up some phrases for use in increasing and
decreasing skill proficiencies, and let authors define the situations
in which they want to deploy those phrases.

> 2) how
> different levels of skill proficiency would even be implemented. I do
> know that I want to stay away from numbers as much as possible ... for
> preference, there would be text states describing skill levels.

If you want textual descriptions of skill levels, you probably also
want authors to be able to specify what those texts should be. I think
the most flexible way to package all this may be with lists.
Basically, have the author specify a list of texts such as {"novice",
"intermediate", "advanced"}. The extension will be agnostic about the
actual textual content, and will instead read this as a skill which
has a maximum skill level of 3 (the number of entries in the list). If
you prefer code (note: none of this code is tested, so there may be
minor issues):

<code>
A skill is a kind of thing. A skill can be learned or unlearned. A
skill has a list of texts called the skill ramp.

A skill has a number called the current skill level. The current skill
level is usually 1.

To decide what number is the maximum skill level of (ability - a
skill):
if the number of entries of the skill ramp of the ability is 0:
say "***Error: No skill ramp defined for [ability].";
decide on 0;
decide on the number of entries of the skill ramp of the ability.
</code>

You'd probably also want to include phrases for changing skill levels,
e.g.:

<code>
To augment the skill level of (ability - a skill):
increase the current skill level of the ability by 1;
if the current skill level of the ability is greater than the
maximum skill level of the ability:
change the current skill level of the ability to the maximum
skill level of the ability.

To augment the skill level of (ability - a skill) by (N - a number):
increase the current skill level of the ability by N;
if the current skill level of the ability is greater than the
maximum skill level of the ability:
change the current skill level of the ability to the maximum
skill level of the ability.

</code>

...as well as to say the skill level:

<code>
To say skill level of (ability - a skill):
say entry current skill level of the skill ramp of the ability.
</code>

Phrases like these allow authors to have the flexibility of being able
to specify the textual descriptions of the skill levels without
directly accessing the lists themselves.

There are probably some refinements that could be made to these
suggestions (and again, I haven't tested them, so you may need to
tweak them a little to get them to work), but hopefully this helps a
bit.

--Erik

Jim Aikin

unread,
Feb 18, 2010, 12:16:43 PM2/18/10
to
Erik's suggestions look solid, but I think he may have omitted an
important factor: One doesn't want to increase the level of a skill
itself; one wants to increase the amount of that skill possessed by a
particular character (which could be the player or an npc). His code
will need to be expanded if you want your extension to allow npc's to
acquire skills and improve them ... which I think is probably a good
idea, if you're writing an extension.

--JA

John G. Wood

unread,
Feb 18, 2010, 3:19:27 PM2/18/10
to
Well, you've seen some good suggestions from Erik and Jim, but I spent
some time on doing this a different way today (before I saw their
replies) so I might as well post it. You can probably get something
from mine as well; although Erik's basic mechanism is more solid (I'm
not an I7 expert), I did start to tackle the issue of other actors, and
it shows a way of having a skill list a user of the extension could
expand upon.

The learning and practicing code is (obviously) way too simple, but it
shows the general idea. Compile it and type "test me".

<begin sample game>
"Skillz" by "John G. Wood"

Book 1 - The Extension Bits

Chapter 1 - Defining Skills

Section 1.1 - Skills and Skill Levels

[First we need to define the available levels. Stealing from the Fudge
RPG:]
A skill level is a kind of value. The skill levels are unlearned,
terrible, poor, mediocre, fair, good, great, and superb.

[The list of available skills should be extensible by the user of the
extension, so put the definitions in a table]
Skill is a kind of value. The skills are defined by the Table of
Skills.

Table of Skills
skill performer level
swimming "swimmer" unlearned
diving "diver" unlearned
running "runner" poor
teaching "teacher" terrible

Section 1.2 - Individualising Skills

[Next we need a way to customise this for each person whose skills
we're interested in]
A person has a table-name called the known skills. The known skills of
a person is usually the Table of Skills.

when play begins:
repeat with P running through people:
if the known skills of P is not the Table of Skills:
repeat with R running from 1 to the number of rows in the
Table of Skills:
choose row R in the Table of Skills;
let S be skill entry;
let L be level entry;
if S is not a skill listed in the known skills of P:
choose a blank row in the known skills of P;
change skill entry to S;
change level entry to L.

Chapter 2 - Changing Skills

Section 2.1 - Practicing

[You can only practice without a teacher if you already know the skill]
Practicing is an action applying to one skill.
Understand "practice [skill]" as practicing.

Check practicing:
if the known skills of the actor is the Table of Skills:
say "Alas, [if the actor is the player]you are[otherwise][the
actor] is[end if] not able to practice skills." instead;
otherwise if the skill understood is a skill listed in the known
skills of the actor:
if the level entry is unlearned:
say "[The actor] can't practice [the skill understood]
without knowing anything about it!" instead;
otherwise:
say "Oops, something's gone wrong...!";
rule fails.

Carry out practicing:
if the skill understood is a skill listed in the known skills of the
actor:
if the level entry is superb:
say "Alas, all [if the actor is the
player]you[otherwise][the actor][end if] can do is maintain your superb
[skill understood] ability.";
otherwise:
change the level entry to the skill level after the level
entry;
say "After a bit of practice, [if the actor is the
player]you are[otherwise][the actor] is[end if] now [level entry] at
[skill understood]!".

Section 2.2 - Learning

[You can only learn from a teacher up to the worst of their skill level
or their teaching level]
Learning it from is an action applying to one skill and one thing.
Understand "learn [skill] from [person]" as learning it from.

Check learning it from:
if the known skills of the actor is the Table of Skills:
say "Alas, [if the actor is the player]you are[otherwise][the
actor] is[end if] not able to practice skills." instead;
otherwise if the skill understood is a skill listed in the known
skills of the actor:
if the level entry is superb:
say "Alas, [if the actor is the player]you[otherwise][the
actor][end if] can't get any better at [skill understood]." instead;
let currentLevel be the level entry;
let instructor be the second noun;
if the skill understood is a skill listed in the known skills of
instructor:
let instructorsCurrentLevel be the level entry;
if instructorsCurrentLevel <= currentLevel:
say "[The instructor] can't teach [if the actor is the
player]you[otherwise][the actor][end if] any more about [the skill
understood]." instead;
if teaching is a skill listed in the known skills of
instructor:
let instructorsTeachingLevel be the level entry;
if instructorsTeachingLevel <= currentLevel:
say "[The instructor] can't teach [if the actor is
the player]you[otherwise][the actor][end if] any more about [the skill
understood]." instead;
continue the action;
say "Oops, something's gone wrong...!";
rule fails.

Carry out learning it from:
if the skill understood is a skill listed in the known skills of the
actor:
change the level entry to the skill level after the level entry;
if the level entry is terrible:
say "[The second noun] teaches [if the actor is the
player]you[otherwise][the actor][end if] the basics of [the skill
understood].";
otherwise:
say "After some teaching from [the second noun], [if the
actor is the player]you are[otherwise][the actor] is[end if] now [level
entry] at [skill understood]!";
rule succeeds;
otherwise:
say "Oops, something's gone wrong...!";
rule fails.

Book 2 - The Sample Game Bits

The Public Pool is a room. "This is where you learn to swim."

The known skills of the player is the Table of Player Skills.

The pool attendant is a man in the pool.
The known skills of the pool attendant is the Table of Attendant
Skills.

Mary is a woman in the pool.
The known skills of Mary is the Table of Mary Skills.

Table of Player Skills
skill level
running great
swimming unlearned
with 10 blank rows

Table of Attendant Skills
skill level
swimming great
teaching fair
with 10 blank rows

Table of Mary Skills
skill level
swimming poor
with 10 blank rows

test me with "practice running/g/practice swimming/learn swimming from
mary/practice swimming/learn swimming from mary/learn swimming from
attendant".

[This bit doesn't work.]
A persuasion rule: persuasion succeeds.
test mary with "mary, practice swimming/mary, learn swimming from
attendant".

<end sample game>


Erik Temple

unread,
Feb 18, 2010, 5:27:50 PM2/18/10
to
Matt, I definitely agree with Jim. I followed the logic you said you'd
already implemented, which focused solely on the player, but his
recommendation that you expand things to work with any actor is sound
advice.

On Thu, 18 Feb 2010 14:19:27 -0600, John G. Wood <ra...@elvwood.org> wrote:

> Well, you've seen some good suggestions from Erik and Jim, but I spent
> some time on doing this a different way today (before I saw their
> replies) so I might as well post it. You can probably get something
> from mine as well; although Erik's basic mechanism is more solid (I'm
> not an I7 expert), I did start to tackle the issue of other actors, and
> it shows a way of having a skill list a user of the extension could
> expand upon.

There are definitely some good ideas here, John. (You also give me an idea
of the kinds of things the OP wants the extension to do!) While I'm not an
Inform expert either, I do have some suggestions for refining John's
suggestions--or at least making them conform more to my idea of how
extensions ought to work!

(1) Define skill levels using a table as was done with skills, so they too
can be extensible. (Note that because skill-levels-as-values apply to all
skills, they are less flexible than the system I suggested; in my example,
swordsmanship could have more steps toward mastery than sweeping, and they
could have different names: "master swordsman" vs. "expert janitor", for
example. This is really only an advantage, though, if you think it
is--maybe you'd prefer for all skills to use the same system; in a game
with a lot of skills, that would certainly be less work for the author.)

(2) Give authors a blank slate of skills and skill levels to work
with--don't hardcode anything if you can avoid it. You can do this by not
including the actual tables in the extension; refer only to the existence
of the table. Individual authors will need to provide a table before the
game will compile, but I don't consider that to be a big issue. So, for
example, you'd include this code in the extension:

Skill level is a kind of value. The skill levels are defined by the
Table of Skill Levels.

And the author would put this in the story file:

Table of Skill Levels
SKILL LEVEL
terrible
poor
mediocre
fair
good
great
superb

(3) "Superb" as the top skill level (and "unlearned" as the bottom) is
hardcoded into John's example, so implementing (2) will require some
tweaking. It is relatively easy to get around this by typecasting, since
under the hood, Inform translates values into numbers. The skill levels
defined in the table above, for example, translate into 1 (terrible)
through 7 (superb). John's code:

> Carry out practicing:
> if the skill understood is a skill listed in the known skills of the
> actor:
> if the level entry is superb:
> say "Alas, all [if the actor is the
> player]you[otherwise][the actor][end if] can do is maintain your superb
> [skill understood] ability.";

...could be changed like this:

<code>


Carry out practicing:
if the skill understood is a skill listed in the known skills of the
actor:

if the level entry as a number is the number of rows in the Table
of Skill Levels:


say "Alas, all [if the actor is the player]you[otherwise][the

actor][end if] can do is maintain your [level entry] [skill understood]
ability.";


To decide what number is (S - a skill level) as a number:
(- {S} -).

To decide what skill level is (N - a number) as a skill level:
(- {N} -).
</code>

Similarly, the "unlearned" level is always equivalent to 1, so you'd say
"if the level entry as a number is 1".

(4) Whether you use something like John's system or my suggestion, I would
recommend using a relation rather than individualized tables to track
knowledge of skills. There are a number of refinements, but in its most
basic expression it might look like this:

<code>
[Extension]
Familiarity relates various persons to various skills. The verb to be
familiar with implies the familiarity relation.

[Game]
The player is familiar with swimming, diving, and teaching.

Check learning to run:
if the player is familiar with running:
say "You already know how to run, you silly gosling!"

Carry out learning to run:
now the player is familiar with running.
</code>


(5) Authors using your extension may have no interest in using your
built-in actions (e.g., practicing, learning). As a player, I'd generally
want to acquire and improve skills through other game activity, rather
than through (relatively mechanical) actions dedicated to those purposes.
You'll probably want to offer rules that an author can call from her own
code to do these things, in addition to offering dedicated actions that
accomplish them. (You might also want to consider instructing authors how
to disable your actions and write their own.)


Regardless of whether you agree with any of these suggestions, I hope they
give you matter to think with as you plan the extension!

--Erik

Adam Thornton

unread,
Feb 18, 2010, 7:56:47 PM2/18/10
to
In article <op.u8cgo...@arik-ohnstads-macbook.local>,

Erik Temple <ek.t...@gmail.com> wrote:
>And the author would put this in the story file:
>
> Table of Skill Levels
> SKILL LEVEL
> terrible
> poor
> mediocre
> fair
> good
> great
> superb
>
>(3) "Superb" as the top skill level (and "unlearned" as the bottom) is
>hardcoded into John's example, so implementing (2) will require some
>tweaking.

You probably mean some fudging.

Adam

Matt

unread,
Feb 18, 2010, 7:57:40 PM2/18/10
to

Thanks, guys!! John, I particularly love your suggestion. I've spent
the past hour tweaking the sample code you provided, and it seems to
be working very well. The only issue is that I never intended to have
a generic "practicing" action; I expected that there would be an
action(s) associated with the skill in question, and then the player
would actually perform that action(s) to get better at the skill.

Sorry if that's unclear ... let me provide an example transcript of
what I was thinking. In this example, I would have included a skill
called fencing, with stabbing, slashing and lunging all associated
with it. (Just to be clear, when the player asks Clay about fencing,
the game has a check rule that interprets it as "learn fencing from
Clay" to make things simpler.)

[transcript]

Dueling Ring
The sand is hot beneath your feet, matched only by the stifling warmth
in the thick, hazy air. Your ears are filled with a repeated metallic
clanging, again and again and again, until your heart seems to beat to
the rhythm of swordplay. In the centre of the ring, your old friend
Thomas is sparring with an old man, their blades a fierce dance of
steel.

In one corner, you can see Clay, your assigned trainer, watching the
duelists with interest.

>>ASK CLAY ABOUT TRAINING
The young man glances in your direction, not even deigning to stand.
"So you're the one they told me about. You've come to learn fighting,
yes? Then go on, ask me about whatever you'd like to learn."

>>ASK CLAY ABOUT FENCING
Clay teaches you the basics of fencing.

After half an hour of intensive drills, the swordmaster finally calls
you to rest. "All right, that's all I'm allowed to teach you," he
pants. "Don't worry, though ... here's an old sabre of mine. It should
be enough to keep you alive."

>>SKILLS
You currently know running (poor), teaching (terrible), and fencing
(terrible).

A hoarse cheer rises up around you, and glance over to see that Thomas
has struck down his opponent. The old man scrabbles around in the dust
for his sword and stumbles out of the ring, humiliated.

>>INVENTORY
You are carrying a much-worn sabre (equipped) and an old robe (being
worn).

>>ATTACK THOMAS WITH SABRE
Sorry, you'll need to explain better than that. Do you want to stab,
slash, or lunge at Thomas?

>>LUNGE AT THOMAS WITH SABRE
You lunge at Thomas with the much-worn sabre, opening a ragged gash
from belly to armpit.

Thomas falls to his knees, badly wounded.

>>STAB THOMAS WITH SABRE
You spin the much-worn sabre and run Thomas through the stomach with
it, cleanly ending his knife.

Thomas' corpse collapses heavily into the sand, blood seeping from his
belly and stomach.

You are now poor at fencing.

[/end transcript]

Okay, so clearly a newbie fighter wouldn't have finished Thomas off
that easily, and wouldn't have gotten a skill increase so quickly
either, but you get the idea. Do you have any ideas as to how I could
neatly implement this into the script? I'm thinking something along
the lines of "Every skill has an action called the training action"
and so on, but maybe there's a better way.

Btw, thanks so much ... this is a great community!

Message has been deleted

Matt

unread,
Feb 18, 2010, 8:27:22 PM2/18/10
to
I forgot to direct your attention in my previous post to where the
"player" typed SKILLS, and it listed all the skills he knew. I've
since been trying to write a simple action for this, but it's more
complicated than I thought. (O.o) I feel like a total newb ... I don't
even remember how to code the "repeat-through-table" thing! It needs
to repeat through the player's known skills, then print the name and
level of every skill in said table that is not unlearned. If anybody
has about three seconds to spare, could you help me out with that?

Erik Temple

unread,
Feb 18, 2010, 8:40:13 PM2/18/10
to

No, no fudging at all! The actual names of I7 values don't matter at the
I6 level, and we can take advantage of that to avoid hard-coding values
into the routines that evaluate the skill levels. I wouldn't call it
fudging...

Adam Thornton

unread,
Feb 18, 2010, 10:31:54 PM2/18/10
to
In article <op.u8cpl...@arik-ohnstads-macbook.local>,

Erik Temple <ek.t...@gmail.com> wrote:
>On Thu, 18 Feb 2010 18:56:47 -0600, Adam Thornton
><ad...@fileserver.fsf.net> wrote:
>
>> In article <op.u8cgo...@arik-ohnstads-macbook.local>,
>> Erik Temple <ek.t...@gmail.com> wrote:
>>> And the author would put this in the story file:
>>>
>>> Table of Skill Levels
>>> SKILL LEVEL
>>> terrible
>>> poor
>>> mediocre
>>> fair
>>> good
>>> great
>>> superb
>>>
>>> (3) "Superb" as the top skill level (and "unlearned" as the bottom) is
>>> hardcoded into John's example, so implementing (2) will require some
>>> tweaking.
>>
>> You probably mean some fudging.

>No, no fudging at all! The actual names of I7 values don't matter at the

>I6 level, and we can take advantage of that to avoid hard-coding values
>into the routines that evaluate the skill levels. I wouldn't call it
>fudging...

Oh, my subtlety is wasted once again as I cast my pearls before
veritable SWINE, I tell you.

The named skill ranks are those of the free (and awesome) RPG Fudge. I
was making a funny that, in retrospect, was intelligible to very few,
and funny to many fewer.

Adam


Erik Temple

unread,
Feb 18, 2010, 10:45:59 PM2/18/10
to
On Thu, 18 Feb 2010 18:57:40 -0600, Matt <jedi...@gmail.com> wrote:

> Okay, so clearly a newbie fighter wouldn't have finished Thomas off
> that easily, and wouldn't have gotten a skill increase so quickly
> either, but you get the idea. Do you have any ideas as to how I could
> neatly implement this into the script? I'm thinking something along
> the lines of "Every skill has an action called the training action"
> and so on, but maybe there's a better way.

I've already said this, but I think it makes the most sense to just
provide a simple rulebook that will upgrade any skill, and make the author
responsible for deploying it. There are just too many variables otherwise.
Maybe there is more than one action that will upgrade the fencing skill
(e.g., "slash", "stab", "slap"), or maybe there are different ways the
author wants to upgrade the skill (only one upgrade for each of multiple
actions, or some skills upgrade only after an action has been done twice,
while others upgrade after three, or...). I don't think you want to tie
the author down too much, which any fully implemented strategy will
inevitably do.

This would be most flexible if you have skill objects (rather than values)
and use an object-based rulebook, but you could do it in multiple ways. If
you're not familiar with object-based rulebooks, they work like this:

<code>
The upgrading rules are an object-based rulebook.

An upgrading rule for a skill (called the ability) (this is the default
upgrading rule):
augment the ability;
say "You are now [skill level of the ability] at [ability]."

An upgrading rule for running:
augment the ability;
say "You feel a surge of power through legs and lungs. Your running
ability has increased to [skill level of running].";
rule succeeds.
</code>

This way, you can provide the default rule, and authors can write other
rules for particular actions. They can also subdivide skills into other
kinds if they want to:

<code>
A physical skill is a kind of skill.

An upgrading rule for a physical skill (called the ability) (this is the
default physical skill upgrading rule):
augment the ability.
say "Your efforts result in a sense of greater control. You are now
[skill level of the ability] at [ability].";
rule succeeds.
</code>

End evangelization. (Object-based rulebooks are one of my favorite
features of I7). Hope this is useful to you, in one way or another.

--Erik

Erik Temple

unread,
Feb 18, 2010, 10:46:49 PM2/18/10
to
On Thu, 18 Feb 2010 21:31:54 -0600, Adam Thornton
<ad...@fileserver.fsf.net> wrote:

Ah, I had a suspicion that fudge meant something...more. But I was
thinking what Stiffy might think, and didn't link it up with the Fudge RPG
(which I've never heard of). And so I played the straight man (any pun
here is intended...)

--Erik

Matt

unread,
Feb 18, 2010, 11:50:06 PM2/18/10
to
On Feb 18, 7:45 pm, "Erik Temple" <ek.tem...@gmail.com> wrote:

Erik, I'll definitely consider what you're saying (possibly for a
later and/or separate release of the extension?), but that isn't
really what I was intending at the moment. Before I think about making
the final extension available to the Inform-using masses, I intend to
distribute it among my friends who, I assure you, don't want to do
that much thinking for themselves. Especially when I get around to
adding the specific combat skills, this extension will be one that
they can just "plug and play," without a ton of customization. Again,
I'm not saying that I don't like the idea, but it's not what I'm
looking for right now.

Erik Temple

unread,
Feb 19, 2010, 6:01:29 PM2/19/10
to
On Thu, 18 Feb 2010 22:50:06 -0600, Matt <jedi...@gmail.com> wrote:

> Erik, I'll definitely consider what you're saying (possibly for a
> later and/or separate release of the extension?), but that isn't
> really what I was intending at the moment. Before I think about making
> the final extension available to the Inform-using masses, I intend to
> distribute it among my friends who, I assure you, don't want to do
> that much thinking for themselves. Especially when I get around to
> adding the specific combat skills, this extension will be one that
> they can just "plug and play," without a ton of customization. Again,
> I'm not saying that I don't like the idea, but it's not what I'm
> looking for right now.

Fair enough. There are serious limitations in trying to do what you want
with stored actions (which is what the OP earlier indicated he was after),
because Inform isn't very flexible when it comes to generalizing actions.
But I got interested in what could be done, and I put together something
close to a best-case scenario:

The biggest limitation Inform has with generalized actions is that you
can't use the Check, Carry Out, or Report rules with anything but a
specific action (such as "jumping" or "buttering the bread"). Because we
don't want the extension to have to directly code any actions, we need to
figure out a way to upgrade a skill based on an arbitrary action w/o
writing specific code for that action. Because we don't have access to
Check-Carry Out-Report, we can't actually print the results of upgrading a
skill during the action rules. We can, however, do so in Instead, Before,
or After--but all of these occur before the Report rules, and so before
the results of the action itself completes. So, we have to defer things
somehow. The code below does this by looping through both skills and
various properties of skills a number of times per turn (at least when an
actor is doing something that could potentially upgrade a skill), and so
it's pretty inefficient. As long as a game doesn't have a mountain of
skills, though, this shouldn't result in a noticeable performance hit.
(Though it could contribute, if we also have a lot of other things going
on).

Another issue with this code as written is that an upgrade will occur
*each time a training action is accomplished*. This is pretty silly, but I
haven't done anything with it because, whatever the OP decides he wants to
do--should we upgrade only after the action has been performed X number of
times? How many times can we upgrade a skill per action? etc.--the
implementation is going to be very fussy. It will probably be necessary,
for example, to track the number of times an action has been performed by
each person in the game. This is likely to be unfun.

Finally the bad beginner's habit of defining behavior other than failure
using Instead rules could cause some users to see the extension as
buggy--actions must complete the Carry Out phase successfully for an
automatic skill upgrade to occur. Since all Instead rules fail long before
the Carry Out phase is reached, it might appear that some actions don't
work properly.

Here's the code. Because it has a lot of indents, I've also put a text
file here:

http://dl.dropbox.com/u/947038/Trainable%20Skills%20example.txt

Good luck!

<code>

Section - Modified code (originally from John Wood)

A skill level is a kind of value. The skill levels are defined by the
Table of Skill Levels.

Table of Skill Levels
SKILL LEVEL

unlearned


terrible
poor
mediocre
fair
good
great
superb

Skill is a kind of value. The skills are defined by the Table of Skills.

Table of Skills
SKILL PERFORMER LEVEL TRAINING ACTION
leaping "leaper" terrible {the jumping action}
dithering "ditherer" terrible {the waiting action, the waving hands action}
running "runner" unlearned --
teaching "teacher" unlearned --


A skill has a text called the player message. The player message of a
skill is usually "You are now a [level] [performer]."

A skill has a text called the NPC message. The NPC message of a skill is
usually "[The current actor] is now a [level] [performer]."

A skill has a list of things called the upgrade-list.

A person has a table-name called the known skills. The known skills of a
person is usually the Table of Skills.

When play begins:


repeat with P running through people:
if the known skills of P is not the Table of Skills:

repeat through the Table of Skills:


let S be skill entry;
let L be level entry;
if S is not a skill listed in the known skills of P:
choose a blank row in the known skills of P;
change skill entry to S;
change level entry to L.

Section - Improving a skill

To augment (S - a skill) for (P - a person), silently:
if S is a skill listed in the known skills of P:
[say "level entry: [level entry as a number]: [number of rows in the
Table of Skill Levels]."; ]
unless the level entry is superb:


change the level entry to the skill level after the level entry;

unless silently:
if P is the player:
say "[player message of S][line break]";
otherwise if the player can see P:
say "[NPC message of S][line break]".

Section - Acting on skill improvements

The action-augmentation is a truth state variable. The action-augmentation
is false.
The current actor is a thing variable. [Inform acts funny if you just add
the actor to the upgrade-list; instead, we put the actor into the current
actor global variable, then add the current actor to the upgrade-list.
This is probably a bug.]

After an actor doing something when the action is skill-noteworthy (this
is the augmentation flag-setting rule):
[This will fire only if the Instead, Before, Check, and Carry out rules
do not derail the action. However, we don't want to print any message
here, because it will fire before the report phase--i.e., we'll be told
that our skill has been upgraded before the results of the action are
printed. So we set a flag and follow up in the every turn phase.]
now action-augmentation is true;
now the current actor is the actor;
add the current actor to the upgrade-list of the implicated skill, if
absent;
continue the action.

Every turn when action-augmentation is true (this is the perform
augmentation rule):
repeat with current-skill running through skills:
if the upgrade-list of current-skill is not {}:
repeat with current-person running through the upgrade-list of
current-skill:
augment current-skill for current-person;
now the upgrade-list of current-skill is {};
now action-augmentation is false.

Section - Phrases to identify skills with actions

To decide whether the action is skill-noteworthy:
repeat through the Table of Skills:
if there is a training action entry:
repeat with action-candidate running through the training action entry:
if the action-candidate is the action-name part of the current action:
decide yes;
decide no.

To decide what skill is the implicated skill:
repeat through the Table of Skills:
if there is a training action entry:
repeat with action-candidate running through the training action entry:
if the action-candidate is the action-name part of the current action:
decide on skill entry;
say "***Error: No skill is implicated in the present action.".


Section - Scenario

The Lab is a room. "Sterile and white."

The Waiting Room is north of the the Lab. "Sterile and beige."

The block jumping rule is not listed in any rulebook.
The block waving hands rule is not listed in any rulebook.

Carry out jumping:
say "You leap, joyfully."

Carry out waving hands:
say "You wave, feeling foolish."

Bob is a man in the waiting room.

First every turn while Bob is in the waiting room:
try Bob waiting.

Test me with "jump / n / wave / jump".
</code>

John G. Wood

unread,
Feb 20, 2010, 5:21:56 AM2/20/10
to
Adam Thornton wrote:
> Oh, my subtlety is wasted once again as I cast my pearls before
> veritable SWINE, I tell you.
>
> The named skill ranks are those of the free (and awesome) RPG Fudge. I
> was making a funny that, in retrospect, was intelligible to very few,
> and funny to many fewer.

Well, it made me chuckle. Though that might say more about me...

John

John G. Wood

unread,
Feb 20, 2010, 5:21:57 AM2/20/10
to
Erik Temple wrote:
> There are definitely some good ideas here, John. (You also give me an idea
> of the kinds of things the OP wants the extension to do!)

Thanks!

> While I'm not an Inform expert either,

The difference is that you've published extensions; I haven't even completed a
game yet.

> I do have some suggestions for refining John's
> suggestions--or at least making them conform more to my idea of how
> extensions ought to work!

OK...

> (1) Define skill levels using a table as was done with skills, so they too
> can be extensible.

This makes a lot of sense to me.

> (2) Give authors a blank slate of skills and skill levels to work
> with--don't hardcode anything if you can avoid it. You can do this by not
> including the actual tables in the extension; refer only to the existence
> of the table. Individual authors will need to provide a table before the
> game will compile, but I don't consider that to be a big issue.

This is not necessary to provide flexibility. You can put the default table of
skill levels in its own section, e.g.,

<code>
Section - Table of Skill Levels

Table of Skill Levels
SKILL LEVEL
terrible
poor
mediocre
fair
good
great
superb

</code>

and then (so long as you use your suggested techniques to avoid referring to
specific levels) the user of the extension can replace the section. That way,
you have an "out of the box" version that can be compiled straight away, but
you're not straitjacketing the user.

Skills themselves I would handle differently. I think there should always be a
teaching skill, so simply put that single skill in the table.

> (5) Authors using your extension may have no interest in using your
> built-in actions (e.g., practicing, learning). As a player, I'd generally
> want to acquire and improve skills through other game activity, rather
> than through (relatively mechanical) actions dedicated to those purposes.

These were just included as samples to illustrate possible ways of using the
skills.

Thanks,

John

Erik Temple

unread,
Feb 20, 2010, 9:17:44 AM2/20/10
to
On Sat, 20 Feb 2010 04:21:57 -0600, John G. Wood <ra...@elvwood.org> wrote:

> This is not necessary to provide flexibility. You can put the default
> table of
> skill levels in its own section, e.g.,

[snip]


> and then (so long as you use your suggested techniques to avoid
> referring to
> specific levels) the user of the extension can replace the section. That
> way,
> you have an "out of the box" version that can be compiled straight away,
> but you're not straitjacketing the user.

There are a couple of things I thought better of after posting, and this
is one of them (the other is the idea of using relations rather than
discrete tables to store information about each actor's skills and skill
levels. There are certainly ways to do it with relations, but your
original system works fine, and is very nicely handled). I have found that
a lot of folks don't know about, or are a bit resistant to, selective
replacement of extension sections--which is why I didn't suggest that--but
you're definitely right. It would be far better to have an extension that
compiles w/o any additional work from the user (as long as the user can
still customize it), and including instructions for replacing the set of
skills in the documentation would ensure this option was open to all.

--Erik

John G. Wood

unread,
Feb 22, 2010, 11:55:33 AM2/22/10
to
I meant to raise a couple of problems I had with my sample code, but
forgot.

1. When defining the individual characters' tables, I needed to leave
enough room to copy the defaults from the Table of Skills. I tried to
do it like this:

Table of Player Skills
skill level
running great
swimming unlearned

with the number of rows in the Table of Skills blank rows

..but I'm not particularly surprised I7 couldn't handle that last
line! Since I was running out of time I just put "with 10 blank rows"
instead, but is there a way to ensure that one table is at least as big
as another?

2. I tried to make the practising and learning code non-PC-specific.
One annoyance was the reported messages, e.g.,

"Alas, [if the actor is the player]you are[otherwise][the actor]

is[end if] unable to practice skills."

Surely there must be a better way to make these messages generic?

3. Notice the last three lines from the sample:

[This bit doesn't work.]
A persuasion rule: persuasion succeeds.

Test mary with "mary, practice swimming/mary, learn swimming from
attendant".

This didn't have the desired effect (or indeed any effect). What needs
to be done differently?

These are side issues, but I didn't think it worth starting another
thread for them.

John


Erik Temple

unread,
Feb 22, 2010, 4:37:35 PM2/22/10
to
On Mon, 22 Feb 2010 10:55:33 -0600, John G. Wood <ra...@elvwood.org> wrote:

> I meant to raise a couple of problems I had with my sample code, but
> forgot.
>
> 1. When defining the individual characters' tables, I needed to leave
> enough room to copy the defaults from the Table of Skills. I tried to
> do it like this:
>
> Table of Player Skills
> skill level
> running great
> swimming unlearned
> with the number of rows in the Table of Skills blank rows
>
> ..but I'm not particularly surprised I7 couldn't handle that last
> line! Since I was running out of time I just put "with 10 blank rows"
> instead, but is there a way to ensure that one table is at least as big
> as another?

No, there's no way to give a table anything other than a constant length,
unless you use the Dynamic Tables extension, which you could use to resize
all of the individual tables to at least the length of the Table of Skills
when play begins.


> 2. I tried to make the practising and learning code non-PC-specific.
> One annoyance was the reported messages, e.g.,
>
> "Alas, [if the actor is the player]you are[otherwise][the actor]
> is[end if] unable to practice skills."
>
> Surely there must be a better way to make these messages generic?

If you use the Plurality extension and define this phrase:


To say the appropriate (A - a thing):
if A is the player:
say "you";
otherwise:
say "[the A]".


...then you will be able write say statements like this:


say "After a bit of practice, [the appropriate actor] [is-are] now [level

entry] at [skill understood]!".


Which is less likely to aggravate one's carpal tunnel.

> 3. Notice the last three lines from the sample:
>
> [This bit doesn't work.]
> A persuasion rule: persuasion succeeds.
> Test mary with "mary, practice swimming/mary, learn swimming from
> attendant".
>
> This didn't have the desired effect (or indeed any effect). What needs
> to be done differently?


You need to use "check AN ACTOR practicing" rather than "Check practicing".

--Erik

Erik Temple

unread,
Feb 22, 2010, 5:20:58 PM2/22/10
to
On Mon, 22 Feb 2010 15:37:35 -0600, Erik Temple <ek.t...@gmail.com>
wrote:

>> 3. Notice the last three lines from the sample:
>>
>> [This bit doesn't work.]
>> A persuasion rule: persuasion succeeds.
>> Test mary with "mary, practice swimming/mary, learn swimming from
>> attendant".
>>
>> This didn't have the desired effect (or indeed any effect). What needs
>> to be done differently?

> You need to use "check AN ACTOR practicing" rather than "Check
> practicing".


Sorry, that might not be very clear if you aren't already familiar with
the use of "an actor" in rule preambles.

When you want an action to work for both NPCs and the player, you need to
write its Carry Out rule preamble(s) with "an actor" as the subject:
"Carry out an actor learning". If you want other rules in the actor
processing rulebook to apply in the same way, you would also use "an
actor": "Check an actor practicing."

"Check practicing"-type rules apply only to the player, while "Check
SOMEONE practicing" applies only to actors other than the player.

--Erik

Matt

unread,
Mar 2, 2010, 11:48:45 PM3/2/10
to
Okay! Sorry I haven't checked back here for a while. Erik, your sample
code works near perfectly; I changed a lot of the descriptions and
level names, but otherwise it's very sound. Of course, there's still
the question of the combat skills themselves and, more broadly, of how
improving skills will actually affect the player's efficiency with
that skill. I know that sounds complex, but basically it would mean
that (every?) action in a game is linked to a certain skill. The
player's level with this skill determines the player's success with
that action, like in most roleplaying games. For example, a player
who's terrible at swordfighting won't have much chance of winning a
duel, but his chances of success improve with each level upgrade.

My only difficulty here is how to implement the action-success
chances. Do we use numbers, percentages, or what? And how would this
fit into the existing extension?

Erik Temple

unread,
Mar 3, 2010, 11:02:48 PM3/3/10
to
On Tue, 02 Mar 2010 22:48:45 -0600, Matt <jedi...@gmail.com> wrote:

> I know that sounds complex, but basically it would mean
> that (every?) action in a game is linked to a certain skill. The
> player's level with this skill determines the player's success with
> that action, like in most roleplaying games. For example, a player
> who's terrible at swordfighting won't have much chance of winning a
> duel, but his chances of success improve with each level upgrade.
>
> My only difficulty here is how to implement the action-success
> chances. Do we use numbers, percentages, or what? And how would this
> fit into the existing extension?


It sounds like you will definitely need to use some sort of numeric system
for this; I guess it's up to you what that system looks like. But since
you've opted to implement skill levels as a KOV, you'll need to find a way
to convert the ramp of values to numbers. There are two main ways you can
do this:

(1) The first I've already indicated how to do: You'd typecast the values
into I6 to convert them to integers; for eight skill levels, you would
have integers 1-8. You could then standardize this so that you're always
working with values from, say, 0-100; this would be useful so that, no
matter how many skill levels an end user defined, the scale would be the
same.

(2) A somewhat more flexible way to do things would be to give each skill
level a number property. This is more flexible because it would allow for
nonlinear skill ramps. For example, if you wanted each step upward in
skill level toward the novice skill level to be more valuable than each
step in skill level at the expert end of the scale, e.g.:

Table of Skill Level Definitions
skill level chance
unlearned 0
terrible 20
poor 38
mediocre 54
fair 68
good 80
great 90
superb 100 (of course, if this is a percentage chance of success
rather than a modifier, you'd never want to award 100%...)

The second is a bit less of a plug-and-play solution, since users would
need to define the skill ramp, but since you're providing a predefined
ramp anyway, that's probably not a big deal.

--Erik

Reply all
Reply to author
Forward
0 new messages