Skip to content

Latest commit

 

History

History
566 lines (368 loc) · 16 KB

Architecture.md

File metadata and controls

566 lines (368 loc) · 16 KB

TAGF (Text Adventure Game Framework) Architecture

This document describes the inner workings of the TAGF code: all the different components and how they interact.

Definition Files

A TAGF game is typically loaded from a YAML definition file, and likewise a game in progress can be saved to a YAML file. Once a game has been built in memory, either by hand or by loading it from a definition file, it can be exported back to a YAML file.

A TAGF definition file is a hash (or dictionary). Most of the top-level keys are the lowerecased names of element classes, either singular or plural. For example, here is an empty definition file:

%YAML 1.2
--- 
game: {}
player: {}
factions: []
features: []
items: []
keywords: []
locations: []
paths: []
npcs: []

The game and player are singular because there's only one of each for any particular game.

The pluralised keys are for arrays of hashes, one per component. Singular forms are rare, because there can be only one entry in the hash with that key, so only one keyword (for instance) could be defined by itself. However, additional keywords could be defined in the same file by putting them into the keywords array, sinc keyword and keywords are different keys in the hash.

I hope that was more clear that it seems on re-reading.

Exportable Elements

Exportable Element Fields

Loading, expoerting, and saving of TAGF games is performed by methods in the TAGF::Filer class. Also in that class is the Loadables, which defines the meaningful keys in the

"Abstracted" Fields

Exporting a Game

The Game Graph

The Graph Configuration File

Exceptions

Exceptions defined by the TAGF package are detailed and instrumented. Some are used internally to signal conditions (such as inventory overflow), and others are used more conventionally to end the application with an explanatory message. Most of the latter apply to logic or dependency issues, and will only be seen by game developers.

Every TAGF exception is assigned a unique numeric identifier, accessible via the #exception_id attribute. This attribute is available for both the exception class and instances of it.

Every TAGF exception also has a numeric severity value, accessible through #severity. By default, when an exception is instantiated, the instance's severity is inherited from the class' #severity value. Unlike the #exception_id attribute, an exception instance's severity can be changed, either at construction by passing a severity: keyword argument to the constructor, or after creation by using the instance's #severity= method.

Every TAGF exception instance also has an #errorcode attribute, which is a combination of its exception ID value and its severity. The errorcode is built by left-shifting the exception ID four bits and ORing it with the severity.

Exception Severities

Every TAGF exception class (and instance thereof) is assigned a severity value (see the overview section on Exceptions. Exception class severities are immutable, but that of exception instances can be changed.

Exception values which are odd numbers (1, 3) indicate either total success or something of note that isn't a problem. Even values indicate some sort of problem.

Success : Numerical value: 1

The application has successfully performed a task. In some cases, processing continues after the message is issued, but this usually is an end-of-run thing.

N.B.: Should be converted to 0 if it's going to be interpreted in situations expecting Unixish shell/libc conventions.

Informational, Info : Numerical value: 3

The application has performed a task, or is providing a status update on one in progress. The message provides information about the process. Generally suppressed, and only used to bring to notice something of interest.

Warning, Warn : Numerical value: 4

The application may have performed some, but not all, of a task. The message may suggest that you verify the result or check for other messages.

Error : Numerical value: 6

The output or result of a task is known to be incorrect, but it may be localised and the application may attempt to continue execution.

Severe, Fatal : Numerical value: 8

The application cannot continue. A severe exception indicates an unrecoverable condition, such as the inability to access a file, or perhaps a logic error has gotten the player stuck. Should always result in an abnormal termination.

Elements, Mixins, and Tools

Components of a TAGF game, such as rooms, NPCs, items, the player itself, and so on, are all called game elements. A Location is an element. A lantern is an element. Everything is an element. All elements include the TAGF::Mixin::Element mixin. All elements are described later in their own section(s).

TAGF::Mixin::Element is only one of the mixins. Features that might apply to disparate elements are separated out and mixed in selectively. For instance, anything that provides light mixes in the TAGF::Mixin::LightSource module; anything that might have contents includes the TAGF::Mixin::Container module, and anything which can be opened or closed (or locked) mixes in TAGF::Mixin::Sealable. Mixins are described in their own section.

Some tools are provided to help game developers, and more will doubtless be added as the need arises. These are described in the Tools section.

Tools

A few tools are part of the TAGF package, and each is accessed from the command line via the tagf command (supplied in the package as bin/tagf). These include:

render

: Allows rendering of the game layout as a visual map in a graphic file. For example,

% tagf render --format=png --source=advent.yaml

will produce a file named advent.png showing all the locations and the paths between them

validate

: Evaluates a game definition (YAML) file and identifies potential mapping errors or playability issues (such as unreachable rooms, rooms that can be entered but not exited, locked items (or doors) with no defined keys, &c.).

% tagf validate --source=advent.yaml

Game Components (Elements)

Faction

Feature

Game

Item

Keyword

Location

NPC

An NPC is a 'non-player character,' and the term refers to any sort of 'character' wholly under the control of the game.

Path

Player

The Player element (of which there should be exactly ONE in a TAGF game) is the virtual avatar of the person playing the game — the User, as opposed to the Player. The Player is controlled primarily by commands entered by the User, but sometimes may be controlled by game dynamics (such as running away randomly if panicked).

Includable Features (Mixins)

Actor

Consumable

Container

DTypes

Element

Graphable

LightSource

Portable

Sealable

UniversalMethods

The UniversalMethods mixin module declares game-wide constancts, methods and attributes that should be available everywhere (such as game settings, or the raise_exception method).

When it is mixed in with include, it also extends itself into the including components' eigenclass (unless it is unnamed, which usually means its a singleton class). So if it is included in class X, all of its definitions are available to instances of X and also to X's class context and methods.

Things Specific to Actors

Attributes

attitude [rw] (Symbol)

: TBS

breadcrumbs [rw] (Array)

: TBS

faction [rw] (Faction)

: TBS

hp [rw] (Float)

: TBS (See the section on Hitpoints)

maxhp [rw] (Integer)

: TBS (See the section on Hitpoints)

Things Specific to Containers

Attributes

allow_containers [rw] (Boolean)

: TBS

capacity_items [rw] (Integer)

: TBS (See the section on Item, Weight, and Volume Limits)

capacity_mass [rw] (Float)

: TBS (See the section on Item, Weight, and Volume Limits)

capacity_volume [rw] (Float)

: TBS (See the section on Item, Weight, and Volume Limits)

current_items [rw] (Integer)

: TBS (See the section on Item, Weight, and Volume Limits)

current_mass [rw] (Float)

: TBS (See the section on Item, Weight, and Volume Limits)

current_volume [rw] (Float)

: TBS (See the section on Item, Weight, and Volume Limits)

is_open [rw] (Boolean)

: TBS (See is_openable, is_surface)

is_openable [rw] (Boolean)

: TBS (See is_open, is_surface)

is_surface [rw] (Boolean)

: TBS (See is_open, is_openable)

is_transparent [rw] (Boolean)

: TBS

Things Specific to Locations

Attributes

light_level [rw] (Float) (See the section on Lighting)

: TBS

paths [rw] (Hash)

: TBS

Things Relating to Events

Attributes

event_queue [r] (Array)

: TBS

events_heard [rw] (Set)

: TBS

Things Common to All Classes

Attributes

article [rw] (String)

: TBS

desc [rw] (String)

: TBS (See shortdesc)

eid [ro] (String)

: The game-wide unique element identifier for the object.

game [rw] (Game)

: The game object that ultimately owns all the other objects. Each object has this attribute, which is how they can find each other.

illumination [rw] (Integer)

: TBS (See the section on Lighting)

is_static [rw] (Boolean)

: TBS

is_visible [rw] (Boolean)

: TBS

mass [rw] (Float)

: TBS

name [rw] (String)

: TBS

owned_by [rw] (Element)

: TBS

only_dim_near_player [rw] (Boolean)

: TBS (See the section on Lighting)

pct_dim_per_turn [rw] (Float)

: TBS (See the section on Lighting)

preposition [rw] (String)

: TBS

shortdesc [rw] (String)

: TBS (See desc)

volume [rw] (Float)

: TBS

Methods

Events

Game Options

The game_options method.

  • EnableHitpoints
  • EnforceCapacities
  • EnforceLighting
  • EnforceItemCounts
  • EnforceMass
  • EnforceVolume
  • RaiseOnInvalidValues

Hitpoints

Lighting

Item, Weight, and Volume Limits

Item Limits

Weight Limits

Volume Limits

Validation and Paranoia Mode

The Game Object

is_container?

: Returns true if the object has mixed in the Mixin::Container module, and can therefore have an inventory and 'own' other objects.

Game Elements

Description goes here.

Class: Element

Description goes here.

Class: Container

Description goes here.

Class: Inventory

Description goes here. See the Inventories section for details.

Class: Location

Description goes here.

Class: Feature

Description goes here.

Class: Item

Description goes here.

Class: NPC

Description goes here.

Class: Player

Description goes here.

Class: Faction

Description goes here.

Inventories

Description goes here.

Relationships Between Elements

Description goes here.

Contributing to tagf

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
  • Fork the project.
  • Start a feature/bugfix branch.
  • Commit and push until you are happy with your contribution. Don't forget to keep up to date with the master branch.
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright

TAGF is copyright (c) 2022 by Ken Coar, and is made available under the terms of the Apache Licence 2.0. See the LICENCE file for further details.