About / Running taf2inf


taf2inf is a program to automate as much of the work in converting a
game from ADRIFT to Inform as possible.  It will not do everything;
you will have to do so


Setup:
Put english1.h, english2.h, and english3.h in the same directory as
your header files.  (These are 1st / 2nd / 3rd person rewrites of
English.h.)  Put everything else in the same directory as the .taf
files you will be converting.

Setting up taf2inf.pl:

If you want taf2inf to create the file with arrow notation:
  Room living_room "Living Room";
  Item -> sword "sword";
  Item -> book "book";
make sure that the line reads 'my $OUTPUT_ARROWS = 1;'

If you instead want it to list parents:
  Room living_room "Living Room";
  Item sword "sword" living_room;
  Item book "book" living_room;
make sure that the line reads 'my $OUTPUT_ARROWS = 0;'


If you want it to generate a simple switch-based keyword matcher for
conversations, make sure $SIMPLE_CONV is set to 1; if you need it to
be able to handle multiword topics, set $SIMPLE_CONV to 0.

Leave $OUTPUT_TO_CONSOLE as 0 and $GUESS_PARSE as 1.



Game-specific modifications:

Find the comment "PUT ANY OBJECTS WHICH ARE TO BE ADDED TO THIS
ADVENTURE HERE".

Note:  if you set any of tmp_objs, tmp_npcs, change_inames, put that
within a block  if ($fn eq '...') { ... } to restrict effects to that
game. 

taf2inf tends to be conservative in choosing the inform names for
objects; for example, in _Goldilocks_, it uses "blackened_metal_poker"
for the "blackened metal poker", when "poker" would have been
sufficient.  If you prefer a different name, put all such pairs into
@change_inames, with the iname taf2inf picks first, followed by the
one you prefer.

ADRIFT allows the author to refer to objects which are not defined; to
help out taf2inf's parser, you may define special objects here.  For
example, if there is a bedroom window which exists in the ADRIFT only
in task commands, you could add it with 
  @tmp_objs = ({ print_name => "bedroom window", vocab => ['bedroom',
'window'], parent => 'bedroom', attribs => [ 'static' ]})
print_name should be the name of the object when printed out; vocab
should be all the words that appear in that object's name property.
parent, if used, should give the iname of its initial parent;
scoped_by, if used instead, should give whichever object
add_to_scope's it; found_in should contain either "[ ; rtrue; ]" or a
space separated list of the inames of all rooms it will appear.

@tmp_npcs is defined similarly.


If there are any verbs used in the game not common to Inform, you may
want to add them to inf-grammar.pl.



After running taf2inf:

taf2inf creates two files.  (filename).inf consists of everything it
could place; (filename).tsk is that which it couldn't fully understand
or place.  You'll need to move tasks from this file to the appropriate
before / after property.

In addition, for any 'unused alr' lines, you'll probably need to move
those to the appropriate place in the .inf file.

Warning: For purposes of showing 'cant_go' messages, NPC movement, and
(possibly in the future) automapping, avoid any side effects in the
direction properties (n_to, s_to, and the like).  Either put such
effects in before/after.Go:, or check to make sure the global variable
'pathing' is false before making changes.

If the game is of even moderate size, there will be a large number of
properties in the 'Globals' object.  Some of those can be simply
removed (for example, if the task ends the game, or if it is tracked
only by 'TASK_REPT', and the task is unrepeatable for other reasons
(successful completion removes an object necessary for the task to
run)); to do so, comment out that property, the line which sets it,
and the parts which check it.  For other properties, move them to
whichever object is appropriate.

Tasks frequently have restrictions of form "if (location == ...)" or
CanSee(player, obj), where obj is an object in the command line; these
restrictions and the corresponding text are unnecessary in Inform and
can be removed or commented out.

If taf2inf puts a 'possibly bad scope' line before a task, it means
that the task does not directly require an object used in the command
line to be present.  This can be a bug in the ADRIFT (the player can
run that task inappropriately), a misparse by taf2inf, or it is
possible that the game forces scope by other means (character starts
in that room and is never removed, but taf2inf can't tell that).  In
such a case, check to make sure the task makes sense.  If it doesn't,
move it to a better place.  You may need to use scoping or phony
objects to get the desired effect.

Find any lines of form "!! EXEC task..." and put in an appropriate call.




Designing games to be friendly with taf2inf.

If you're writing an ADRIFT game, and want it to be convertible, then
try to design with these rules in mind:

- Any object the player can refer to in a task command must be defined
  as an object

- Any task command not meant to be typed (such as the name for an
  event-called task), should begin with a hash (#).

- Minimize the number of tasks that can be called from more than one 
  place. For example, instead of (Task A calls tasks X,Y,Z and task B
  calls tasks X,Y,Z, have task A call task W, task B call W, and task
  W call tasks X,Y,Z.)

- Be consistent about the structure of task commands.  Each command
  should start with the name of the character being ordered (if the
  command is to be an order), followed by the verb (which should
  appear intact), followed by the objects.  (Particularly, don't use
  wildcards around the verb.)

- Make all tasks repeatable unless you need ADRIFT to prevent it from
  occuring more than once.  For example, if a task ends the game, it
  doesn't matter to ADRIFT whether the task is repeatable or not; the
  game will be over, so the player can't repeat it anyway.
  Alternately, if 'DRINK POTION' has a restriction 'potion must be
  held by player', successful execution removes the potion, and
  there's no way to get another one, again, the player can't repeat 
  the action in any case.  But taf2inf can't analyze the game to that
  degree, so it has to track those tasks itself.

