# Core and Optional Modules

The adv3Lite library has been designed to be as modular as possible, so that if there are features of library you don't need for a particular game you can easily exclude them from the build (on how to do this, consult the System Manual). Some of the modules, however, are core to the library and must be included in every game. Moreover, a few of the optional modules require other optional modules to be present. In this section we list the core modules and offer a brief explanation of the optional ones.

Note that all modules, core and optional, are included in the library by default, so that all the features of the library are available to you when you start a new game. It's up to you do decide which features you don't need or want to use, and to opt out of them by excluding them from your build if you so wish.

NOTE: if you exclude an optional module once the game has been compiled (as a new game automatically is by Windows Workbench) you may need to do a complete recompile for debugging after excluding the unwanted modules; otherwise you may get a number of spurious errors and warnings.

## Core Modules

In addition to the TADS 3 System files (the ones that some in the system.tl library file that is usually contained automatically in any TADS 3 complilation), any TADS 3 game built with the adv3Lite library must include the following files from the adv3Lite library:

- action.t
- actions.t
- banner.t *
- command.t
- console.t *
- doer.t
- debug.t **
- debug_dynfunct.t **
- input.t
- lister.t
- main.t
- messages.t
- modid.t
- output.t
- parser.t
- precond.t
- query.t
- spelling.t
- status.t
- thing.t
- travel.t
- english.t ***
- grammar.t ***
- tokens.t ***

* console.t and banner.t are required for traditional TADS 3 games played on an interpreter. These files are not included in the adv3LiteWeb library used for games to be played via the Web UI; for web-based games browser.t is used in place of console.t, and banner.t is not used at all.

** The debug.t and debug_dynfunct.t files are only included in debug builds; they therefore have no effect on the size of the released game. Note that if you include dynfunc.t in your game you should not include debug_dynfunc.t, since the latter simply includes dynfunc.t in a game compiled for debugging, and you won't want it twice!

*** english.t, grammar.t and tokens.t are specific to English language games. Games written in another language would need to replace them with that other language's equivalents.

## Optional Modules

The following modules are optional, but (where noted below) may require the presence of other modules:

- actor.t: Provides support for implementing NPCs including conversation and agenda items. Requires events.t and topicEntry.t.
- attachables.t: Implements classes for simple types of attachable, including SimpleAttachable, NearbyAttachable and Component.
- eventList.t *: Implements various types of EventList (identical to those in the adv3 library).
- events.t *: Implements fuses and daemons.
- exits.t *: Implements the status line exit-lister and the EXITS command.
- extras.t * Defines a whole load of classes such as Fixture, Container, Supporter and the like familiar from the adv3 library. This file implements some additional functionality through a number of its classes, while others simply implement effects that could readily be obtained by defining various properties on Thing; many authors will probably want to include this file for convenience and more readable code.
- facts.t: Provides more sophiscated tracking of who knows what. Requires topicEntry.t., thoughts.t and actor.t
- gadget.t *: Implements classes for control gadgets such as buttons, levers and dials.
- hintsys.t *: Implements a hint system (almost identical to that in adv3). Requires menusys.t, menucon.t and events.t
- intruct.t: Provides a game with a set of basic instructions on playing IF. Requires menusys.t and menucon.t to display instructions in menu format.
- menusys.t * and menucon.t: Implement the system for displaying menus. Note that these two files must be included together (i.e. your game must include both or neither). In a webui game menucon.t is replaced with menuweb.t.
- newbie.t: Provides various kinds of assistance to new players. Requires events.t
- pathfind.t: * Implements pathfinding, both for NPCs (if desired) and for the player character (via use of GO TO and CONTINUE commands).
- scene.t: Implements a Scenes mechanism similar to that found in Inform 7.
- scenery.t: * Provides a shorthand means of defining multiple Deoorations.
- score.t: * Implements a scoring system identical to that in the adv3 library. Exclude this file to disable scoring if it is not relevant to your game.
- senseRegion.t : Implements the SenseRegion class which allows a game to define regions of two or more rooms with sensory connections between them.
- topicEntry.t: Implements the base class for Topic Entries along with the Consultable and ConsultTopic classes.
- thoughts.t: Provides the framework for a THINK ABOUT command. Requires topicEntry.t.

( * = also included in adv3Liter, for which see below)

Note that in addition to the optional modules listed above, there are a number of extensions, which can further extend the functionality of adv3Lite. The difference between an optional module and an extension is that you have to choose to opt out of using an optional module (by deliberately excluding it from your game), whereas you have to deliberately opt in to an extensions (by taking the appropriate steps to include it in your game). In principle optional modules implement features that many games are likely to need, while extensions offer more specialized features that fewer games are likely to need, although in practice the distinction between the more popular extensions and the lesser used optional modules may turn out to be a little fuzzy in this respect. It is in any case worth being aware of what extensions are available in case one or more of them implements features you need in your game.

## Options and Alternative Libraries — Lite, Liter and Litest

Adv3Lite comes in three flavours: adv3Lite, adv3Liter and adv3Litest (see below on the naming here). The first of these, adv3Lite, is the full library, with all the core and optional modules included. The third, adv3Litest contains only the core modules. The second, adv3Liter contains the core modules plus a selection of the more commonly used optional ones.

In practice, most people will probably use the full adv3Lite library, since the presence of unneeded modules does very little harm (beyond, perhaps, misleading players into supposing your game implements features such as hints and scoring even if they don't).

You could write a game using adv3Liter if it doesn't contain any NPCs (or has only one or two very simple NPCs - for an example see below). Adv3Liter would easily enable you to write a game similar to what could readily be produced by Inform 6 or TADS 2, with a few extra features besides. It would not be bad choice for your first game (the first two games in the Adv3Lite Tutorial could be written using adv3Liter) and would likely be perfectly adequate for a game involving a lone player character mainly interacting with their physical environment, with either no or only very simple NPCs.

Very few people are likely to want to use the advLitest library, except as a progamming challenge or learning exercise, although you could write a game with it. One of its main functions is to test the modularity of the library (checking that a game based solely on the core modules will compile is a way of ensuring that unintended dependencies between different modules haven't been overlooked). Another possible reason for using adv3Litest would be if you wanted to write a game where things work very differently from the way in which they do in the adv3Lite library so you'd rather devise your own versions of the functionality you need, using adv3Litest as a starting point. If you wanted to do something radically different you could even start from adv3Litest and then exculde thing.t, travel.t, grammar.t and/or english.t (say) and replace them with your own equivalents tailored to your own requirements.

Whichever version of the library you choose to start a new game with, you're not stuck with the list of modules it provides. You can delete modules from your game or add additional ones to it, either in Workbench or by editing the game's project file (for which see the chapter on Compiling and Linking in Part II of the TADS 3 System Manual). Or, even more radically, you could remove one version of the library from your game altogether and replace it with another.

### Naming Conventions

Had I known how adv3Lite would turn out, I'd probably have called it something different. As things are now, the suffix 'Lite' has become somewhat misleading, since adv3Lite is hardly Lite in comparison with adv3, just different in some respects, fuller in others, and more modular overall, allowing users to opt out of more features they neither need nor want (should they indeed neither need nor want them). However, the name adv3Lite has probably become too well established to change now.

What I'm now calling adv3Liter is arguably what adv3Lite might have been if it had stuck to being a genuinely Lite alternative. The 'Liter' in adv3Liter indicates something that is indeed Liter both in relation to the full adv3Lite and to adv3. Although looking at the list of optional modules in advLiter may suggest that not many have been left out (from the full adv3), many of those that haven't been included in adv3Liter are amongst the most complex in the full adv3Lite library,

The core modules bundled as adv3Litest represent the bare minimum needed to create a game. I thought of calling it adv3Min (for minimal), but that would have made it less clear that it's a minimal form of adv3Lite rather than of adv3. The names adv3Lite, adv3Liter, and adv3Litest make the relationship between the three reasonably clear.

(What is now called adv3Litest used to be called adv3Liter, but I believe the new nomenclature makes better sense. I suspect that hardly anyone has attempted to create a game using what was adv3Liter and is now adv3Litest, so this change should have no advserse effect, beyond any existing adv3Liter games perhaps finding they have gained a slew of optional library modules they didn't have before).

### Example of Simple NPC implemented in adv3Liter

As mentioned above it's perfectly possible to implement very simple NPCs in adv3Liter (or even adv3Litest). By way of illustration, below is a possible implementation of an adv3Liter oracle that can give answers to simple questions such as ASK ORACLE ABOUT LIFE or CONSULT ORACLE ABOUT VICTORY. It would be a fairly simply task to expand the range of responses, but anything much more complicated would probably best be implemened using the full adv3Lite library. Anyone wishing to experiment with adv3Liter is, of course, welcome to copy the code below and adapt it to their own needs.

    oracle: Actor 'oracle;strange;being;her' @oracleRoom
        "The oracle is a strange being, half woman, half sphinx and half hedgehog. "

        specialDesc = "The oracle sits in the corner, waiting for you to speak. "

        /*
         *   Make asking the oracle about something equivalent to consulting the oracle about something.
         */
        dobjFor(AskAbout) asDobjFor(ConsultAbout)

        /*  So make the oracle consultable */
        isConsultable = true

        dobjFor(ConsultAbout)
        {
            preCond = [objVisible, objAudible]

            action()
            {
                /*
                 *   Noting that oracle is our current interlocutor will allow subsequent short-form
                 *   implicit ask commands (e.g. A ROAD).
                 */
                gActor.currentInterlocutor = self;

                /*
                 *   Try to obtain a response corresponding to the topic asked about from our table of
                 *   answers.
                 */
                local resp = answers[gTopicMatch];

                /* If we find one, display it wrapped in a suitable sentence. */
                if(resp)
                    "<q><<resp>>,</q> the oracle <<one of>> replies<<or>>tells you<<or>>avers<<or>>
                    proclaims<<or>>announces<<shuffled>>. <.p>";

                /* Otherwise respond with a blandly Delphic default. */
                else
                    "<q>It all depends what you mean by <q><<gTopicText>></q>,</q> she says.<.p>" ;
            }
        }

        /* Define a LookupTable with the oracle's answers on various topics */
        answers = [
            tLife -> 'Life is a mystery',
            tDeath -> 'Death is the absence of life',
            tVictory -> 'The road to victory can take many unexpected paths',
            tMeaning -> 'Life means whatever meaning you give it.',
            tRoad -> 'There\'s many a road that leads nowhere, and some that lead somewhere,
                and a few that lead where you may want to go, and others that lead you
                where mortals dread to tread',
            oracle -> 'I speak what you are fit to hear; the rest is up to you',
            me -> 'You are what you are, therefore know thyself'
        ]

        /* This is necessary to allow short-form implicit ASK commands, like A ROAD.*/
        handleTopic(topicListProperty, topics, defaultProperty)
        {
            actionDobjConsultAbout();
        }

        /*
         *   When the player character leaves, reset their current interlocutor to nil and show a
         *   farewell message from the oracle.
         */
        beforeTravel(traveler, connector)
        {
            traveler.currentInterlocutor = nil;

            "<q>Farewell!</q> says the oracle. <.p>";
        }

    ;

    tLife: Topic 'life';
    tDeath: Topic 'death';
    tVictory: Topic 'victory';
    tRoad: Topic 'road';
    tMeaning: Topic 'meaning of life';

Note that the Actor class we'd be using here is a minimal implemtation defined in thing.t, not the full-blown Actor class defined in actor.t (which modifies thing.t's minimal definition and provides 99% of Actor's functionality beyond what it is already defined on Thing).

## Which Optional Modules Do You Need?

You may be wondering, since some of the library modules are optional (and also since there are different libraruyversions) how to determine which ones you actually need. If you like, you can simply opt for the full adv3Lite library and leave them all in place in your game, nothing will go horribly wrong as a result, but if you want to be more discriminating, the following guidelines may be of some help. For this purpose, it may be helpful to think of the optional modules in the following groups:

Extras, EventLists and Events: while it is possible to write a game in adv3Lite without any of these three modules (otherwise they wouldn't be truly optional), all three of them are likely to prove useful for the majority of games, so you should normally include them unless you have good reason not to.

Exits and Pathfind: both these modules provide ease of use for players without creating any additional work for game authors, so they are normally worth including except in games with very few rooms. If you're writing a one-room game these two modules are completely pointless and could be excluded. For games containing two or three rooms these two modules may not add much, but whether or not to include them will partly depend on your aesthetic choice. Games with four or more rooms will normally benefit from having these modules included.

Attachables, Gadget, SenseRegion and Thoughts: Each of these modules provides implementations that the majority of games may not need, and so only need to be included if your game actually requires the functionality they provide (although it is, of course, harmless to leave them in). Attachables is useful if and only if you have objects the player needs to be able to attach to and/or detach from each other. Gadget is useful if your game makes use of buttons, levers and dials, but not otherwise (so it is, for example, unlikely to be useful in a game set some way in the past). SenseRegion is useful if you want it to be possible to see, hear and or/smell objects in one room from another (so that, for example, it would clearly be useless in a one-room game). Thoughts provides a framework for implementing a THINK ABOUT command, and is only useful if that's something you want in your game.

Menusys, Hintsys and Score: Hintsys need only be included if your game implement hints, and Score need only be included if your game keeps score; excluding either of these modules may make it clearer to your players that your game does not implement the relevant features. If you included Hintsys you must also include Menusys, but you may also want to include Menusys for other purposes, for example to offer players a menu of options in response to an ABOUT command.

Instruct and Newbie: Both these modules provide help for new players of Interactive Fiction and are almost certainly worth including if such new players are likely to be in your target audience. Note that Instruct works better if Menusys is included, and that Newbie can usefully be supplemented by features in Hintsys.

Scene: The Scene module probably doesn't allow you to do anything you couldn't do without it, but it may well enable you to do it in an easier way. Scenes (which it implements) are basically objects that become active and inactive under circumstances you specify and which can carry out specified tasks when beginning and ending and while they're active; this can often be a convenient way of organizing events in a game. If in doubt, leave this module in unless and until you're sure you don't need it.

Scenery: The Scenery module certainly doesn't allow you to do anything you couldn't do without it, but does make it easier to define and manipulate multiple decoration objects, which could be useful if you make heavy use of Decorations in your game. But even if you don't, there's absolutely no harm in leaving the Scenery module in your build.

Facts: The Facts module is rather more specialised, providing a more systematic way of keep who knows what and who's said what to whom in a game in which several NPCs (and possibly multiple player characters) are exchanging potentially important information and/or the player character is looking up important information in/on various Consultables (such as books or electronic devices). While on a modern computer the presence of the Facts module is unlikely to do any noticeable harm if it's left redundantly in a game that doesn't use it, if you are concerned about computing resources, the Facts module might be a good one to exclude from your game if you don't need it.

Actor and TopicEntry: You almost certainly need these two modules if your game is going to include NPCs (non-player characters) of any sophistication, but probably not otherwise. You don't need the Actor module to define the Player Character (which can simply be a Thing), nor do you need it to define simple NPCs such as animals or guards whose role is simply to block access to somewhere until they're removed. On the other hand, if your game is going to include anything more than the most basic conversation with one or more NPCs then you almost certainly will require the Actor module (along with the TopicEntry module on which it depends) — at least it will if you plan to use an ask/tell type conversation system. If you want something completely different, such as a menu-driven conversation system or a simple TALK TO system you may prefer not to include the Actor module but instead write your own replacement for it. Note that you will also need the TopicEntry module if your game includes Consultables (such as books the player character can look things up in) or you want to include the Thoughts module.

adv3Lite Library Manual
Table of Contents | Opening Moves > Core and Optional Modules
Prev: Introduction Next: Minimal Game Definition