                             Change Log for WolfMUD

This document details the main highlights for each release of WolfMUD. For
detailed information on changes please see the WolfMUD git repository:

                   git clone https://code.wolfmud.org/WolfMUD


v0.0.19-beta.1 Released Sunday 31st October, 2021
==============================================================================

Added

  - Player commands can now refer to SELF and MY. For example "examine self",
    "drop my sword", "drop all my weapon". The MY reference currently only
    works on items in a player's inventory. If a player drops an item it is no
    longer considered theirs until they pick it up again.

Changed

  - Nearly everything... the experiment branch has moved to the dev branch.
    Version v0.0.19 will be a complete rewrite of WolfMUD v0.0.18 from the
    ground up. The only code kept from v0.0.18 is the recordjar package. The
    text package is mostly intact with some clean-up, Fold has been rewritten.
  - The zone files are the same as v0.0.18 apart from a few fixed typos.
  - The Makefile and build files are the same as v0.0.18, apart from a minor
    tweak for retrieving versions from Git.
  - The docs directory is from v0.0.18 and may be a little inaccurate.
  - Existing player files should continue working 'as is'.
  - Barriers to limit mobiles to an area are not implemented yet.
  - Player health is not implemented yet.
  - The player commands HIT, TALK, TELL, WHICH, WHISPER, WHO and /PROMPT are
    not implemented yet.
  - The behaviour of some player commands may differ to v0.0.18 and all player
    commands need to be reviewed.

Known Bugs / Issues

  - The player display when quitting needs cleaning up.
  - Network quotas are not implemented yet.
  - IP addresses of players appear in the server log.
  - Configuration settings are hard-coded and not via a configuration file.
  - The commands #DUMP, #TELEPORT and #GOTO can be used by anyone.
  - The #DUMP command output can be messy if there are long "words" that cannot
    be broken on white-space.
  - Statistics are not periodically logged by the server yet.
  - Removal of stop words not implemented yet. This means "examine apple" will
    work while "examine the apple" will not.

v0.0.18 Released Sunday 11th April, 2021
==============================================================================

Module Mode

  - WolfMUD now uses Go's module mode instead of the older GOPATH mode. As a
    result the use of 'go get' to obtain WolfMUD is considered deprecated. The
    preferred method of obtaining WolfMUD is Git and cloning the repository.
    Alternatively the binary and source archives are provided for each release.

Added

  - Zone files can use @refs to reference fields defined at another reference.
  - Fields in a record jar can have an optional preferred ordering applied when
    the record jar is written. The default preferred ordering for WolfMUD is
    specified in the attr/ordering package and can be changed to suit.
  - The preferred ordering of fields in a zone file is now documented and is
    intended as a guide to ease collaboration between authors. Details can be
    found in docs/zone-files.txt.
  - New wrjfmt tool for formatting record jar files. See Known bugs / Issues.
  - An optional Makefile is provided for building, testing and running WolfMUD
    on Linux during development.
  - An optional Makefile is provided for building WolfMUD releases on Linux.
  - A new botrunner tool has been added to simulate players on the server for
    load testing.

Changed

  - The supplied zone files have been cleaned up and make use of the new @refs.
  - Player files are now written out with the preferred field ordering.
  - Minor performance improvement inlining state.CanLock check in state.AddLock
  - Network writes to clients are now asynchronous. This improves performance
    when handling player commands. Clients on a slow connection are handled
    better and no longer hold up other players.
  - All commands and tools should now be placed in the bin directory.
  - Default data directory for binary, source and Git clones is ../data
  - Default root directory for binary, source and Git clones is WolfMUD. The
    instructions for Git clone on the website and in documentation is now:

      git clone https://code.wolfmud.org/WolfMUD

  - Most documentation in the docs directory has been rewritten/ improved.

Deleted

  - The documentation in getting-started.txt has been incorporated into the
    running-the-server.txt and compiling-from-source.txt guides.

Fixed

  - Fixed an issue in record jars where the name of the free text field was
    included at the beginning of the text if a named free text field was used
    as opposed to an unnamed free text section.
  - Fixed a formatting issue when writing out free text sections. Free text
    sections are now unfolded and refolded when being written out.
  - Fixed a comment in the text package which was causing the copyright notice
    to appear as a package comment.

Known Bugs / Issues

  - The new wrjfmt tool is a work in progress and has several limitations,
    however it has been made available 'as is' due to the benefits provided
    when used to clean up the zone files.

      - Comments will be stripped from the record jar
      - String lists will be compacted
      - Camel cased field names will be title cased
      - Named free text fields will become free text sections

    Despite these limitations, it is very useful when formatting a zone file
    and comparing the output with the original zone file, using a text diff
    program, and manually applying changes.

  - The new Makefiles for WolfMUD and building releases are currently only for
    Linux and rely on Bash.

v0.0.17 Released Saturday 31st October, 2020
==============================================================================

Added

  - New ref field added to Thing to store the original reference from the
    record jar. Accessed via a new Thing.Ref method.
  - New Inventory.SearchByRef method to search Inventory by Thing ref.
  - New LoadHooks and SaveHooks methods added to Thing to provide hooks into
    the post-unmarshaling and pre-marshaling processes.
  - New ResetHooks added to Thing to provide hooks into the reset process.
  - New Holding, Wearing and Wielding attributes to record what items a player
    or mobile is using and how the items are being used.
  - New saveHook added to Body attribute to make Holding, Wearing and Wielding
    attributes available for saving to a record jar.
  - Added a cuirass (ref: L11O1) and helmet (ref: L11O2) to stock inventory for
    armourer in data/zones/zinara.wrj.
  - Toy doll (ref: O11) wearing a dress (ref: O12) and hat (ref: O13) added to
    pawn shop (ref: L8) in zinara.wrj - for testing and experimenting with
    returning containers to their initial state including used items. Toy doll
    has WAIT set on Reset.
  - New WAIT value added to Reset attributes that cause mobiles/containers to
    wait for their inventory items to be ready before resetting.
  - New Inventory.SearchDisabled method added to search an Inventory disable
    list for a Thing matching an alias.
  - The Body attribute has a new RemoveAll method to unconditionally remove all
    items being used.

Changed

  - Loading players calls post-unmarshaling LoadHooks on Thing.
  - Saving players via QUIT command calls pre-marshaling SaveHooks on Thing.
  - The EXAMINE/EXAM command now details items being used by players and
    mobiles.
  - City guards (ref: M11 & M12) updated to wield a shortsword (ref: L13O1) and
    wear a helmet (ref: L11O2), cuirass (ref: L11O3), leather breeches (ref:
    L73O1) and boots (ref: L73O7). Mobiles have WAIT set on reset.
  - Sweet flower girl (ref: M7) updated to wear a dress (ref: M7O2) and hold a
    bunch of wild flowers (ref: M7O1).  Mobile also has WAIT set on reset.
  - Optimised Inventory move when from and to Inventory are the same.
  - The $RESET command now implements waiting for mobiles/containers with the
    new Reset WAIT value set.
  - The $RESET command now calls Thing.ResetHooks to provide access to the
    resetting process.
  - #DUMP/#UDUMP/#LDUMP can now be used directly on disabled items.
  - The JUNK command will now synchronise body slots when items are junked.

Fixed

  - Duplicate 'reference' removed from message text in zones.loadZone when
    overwriting duplicate references.
  - Data race fixed when player killed just as they submit a command for
    parsing.
  - The Body attribute Hold, Wear & Wield methods now check for Body being nil.
  - In data/zones/zinara.wrj remove duplicate aliases on the cotton shirt (ref:
    L73O11), cotton trousers (ref: L73O12) and cotton dress (ref: L73O13).

v0.0.16 Released Thursday 10th September, 2020
==============================================================================

Added

  - New Thing.Freed method added to use in place of 'len(Thing.Attrs()) == 0'
    to reduce allocations and copying.
  - All Attributes now have an Is method that return true if the Attribute
    implements a particular interface - usually the interface named for the
    attribute type.
  - New Thing.FindAttr and Thing.FindAttrs methods which use the new Attribute
    Is method to replace the current Find* methods.
  - Removed Thing.Attrs method.
  - Added Attribute.free method to free Attribute without locking.
  - New Health attribute added. Players automatically upgraded on login.
  - New player /PROMPT command to set/query current prompt.
  - Experimental HIT command added for testing new Health attribute and health
    regeneration. Can be vetoed via HIT or the more general COMBAT pseudo
    command.
  - New cmd.state.asParticipant method to allow an actor to script a command
    for a participant.
  - Players can be killed in-game, currently via the experimental HIT command.
  - A hyphen '-' or underscore '_' can now be used in the name of a name/value
    pair in a record jar file and will no longer be interpreted as a name/value
    separator.
  - A exclamation mark '!' can precede the name in a name/value pair list in a
    record jar file and will not be treated as a name/value separator.
  - Added a text.List convenience function for turning a []string into a string
    that is comma separated except the last two elements which have 'and'
    between them. For example: text.List("A", "B", "C") → "A, B and C".
  - A new Body Attribute has been added allowing items to be worn, wielded and
    held. Players are automatically upgraded on login.
  - New REMOVE command to stop wearing, wielding or holding an item.
  - New Wieldable, Wearable and Holdable Attributes added. Documentation in
    docs/zone-files.txt updated. While Wieldable and Wearable have to be
    defined on an item Holdable (in one hand) is applicable to all items except
    players and mobiles. Holdable can be vetoed if something should not be
    held. Specifically defining Holdable on an item can override the default
    behaviour, for example to require two hands.
  - New WEAR, WIELD and HOLD player commands added.
  - Added Merkle's Fine Emporium (clothier, L73) with a selection of clothing
    items that players can wear.
  - Added a text.tree sub-package for producing textual tree graphs.
  - Added new attr.Thing.DumpToLog helper method.
  - Queued events now record when they are expected to fire. Queued events can
    also be suspended and will record how long is left before they are due to
    fire. Suspended events can be resumed to fire after the remaining time.
  - The Action, Cleanup and Reset attributes have new Suspend and Resume
    methods to suspend and resume their events.
  - Added a attr.Reset.Spawnable method to check if an item is spawnable.
  - Added a attr.Reset.Unique method to check if an item is unique.
  - New SHOUT, TELL/TALK and WHISPER player commands added.
  - New test zone reset.wrj added under data/zones, disabled by default. Old
    test zone quiet.wrj removed.
  - In the zinara.wrj zone file there are two new barriers. One to stop the
    rabbit and frog from wandering out of the gardens, the other to stop random
    creatures wandering into the gardens.

Changed

  - Lazily allocate maps in message.Buffers.Silent to reduce allocations.
  - $CLEANUP and $RESET commands updated to use new Thing.Freed method.
  - All Attribute Find* methods reimplemented using Thing.FindAttr and
    Thing.FindAttrs methods. Cleaner implementation causes an average 5%
    performance hit to in-game commands. Needs revisiting.
  - The event package now uses a reference to attr.FindName instead of manually
    processing the result of calling attr.Thing.Attrs - a butt ugly hack that
    allows attr.Thing.Attrs to be removed.
  - The frontend package now locks the outermost Inventory of the player's
    starting position when player is placed into the world.
  - attr.Locate now uses the sync.rwmutex from the embedded Attribute instead
    of allocating its own.
  - Player prompt displays current / maximum health, dependant on prompt style.
  - Default player prompt changed from StyleBrief to StyleShort.
  - The frontend package now uses a player's attr.Locate.Where being set to nil
    as an signal to exit, instead of checking if the last command was 'QUIT'.
    This allows other means of exiting, such as being killed ;)
  - The Dragon's breath tavern and the sheltered area in the garden have been
    reinstated as sanctuaries - no fighting/combat allowed.
  - The city guard's peacekeeper status has been partially restored - they can
    prevent fighting, but cannot attack players killing things in return.
  - The message.Buffer.Deliver has been optimised, avoids copying buffers.
  - The QUIT command has been updated to sync body slots when forcibly junking
    non-collectable items the player cannot keep.
  - The DROP and PUT player commands have been updated to sync body slots when
    a worn, wielded or held item is dropped or put somewhere.
  - The INVENTORY/INV player command shows items being worn, wielded or held.
  - Clarify SPAWN and unique item documentation for RESET in docs/zone-files.txt
  - In docs/zone-files.txt the section on Alias/Aliases has been rewritten and
    now includes details of qualified and bound aliases.
  - Cleaned up chest, pouch and ball references and moved items from the tavern
    to the trading post in the zinara.wrj zone file.
  - Moved the curious brass lattice from the tavern to the pawn shop in the
    zinara.wrj zone file.
  - Added specific Holdable definition to rabbit and frog mobiles in zinara.wrj
    so that they can be held by players - mobiles are not normally holdable.
  - Moved bag and sack from tavern to the trading post in zinara.wrj zone file.
  - The EXAMINE/EXAM command has been updated so that when used on another
    player it describes items being worn, wielded or held.
  - attr.Thing and all Attribute switched to new debugging scheme using new
    text.tree package. Debugging information for attributes standardised.
  - Removed ability to dump Thing by arbitrary memory address using #DUMP.
  - Updated #DUMP to use new debugging scheme.
  - The attr.Thing.Copy method has been renamed attr.Thing.DeepCopy and is
    recursive into Inventory. The attr.Thing.Copy method has been reimplemented
    and is not recursive.
  - Removed Thing.ClearOrigins method as no longer used.
  - In the zinara.wrj zone file the "weapon shop" is now "bladesmith workshop"
    and has a selection of weapons to try with the new WIELD command.
  - The game.init method has been renamed game.enter to better reflect its
    purpose and to avoid confusion with package init methods.
  - Updated the meaning of what is a collectable item in  the Thing.Collectable
    method. Updated junk.dispose method as it can no longer use the Collectable
    method to determine if an item should be freed for garbage collection.
  - The SAVE command now also saves a player's disabled items waiting for a reset.
  - When a player exits the game any pending Reset events are suspended, when
    entering the game any suspended Reset events are resumed.
  - The attr.Inventory.Unmarshal method has been updated so that references
    with a leading exclamation mark '!' are loaded disabled.
  - The SAVE command cmd.save.fixInventory method, frontend.log.assemblePlayer
    method, zone loader zone.linkupInventory and zone.linkupLocation methods
    have been updated to understand disabled references. This means players can
    be loaded with disabled items, usually because they are waiting for a
    reset. Also items can be loaded disabled into zones via INVENTORY and
    LOCATION fields. Documentation in docs/zone-files.txt updated with details.
  - Added 'to' and 'with' as stop words in cmd.internal.stopwords so that
    players can 'TALK with' and 'WHISPER to' other players.
  - The street vendor in the zinara.wrj zone file now uses SHOUT instead of SAY
    to attract potential customers.

Fixed

  - Don't try logging a connection error if there isn't one.
  - Thing.Freed only needs to take a read lock instead of a read-write lock.
  - Missing comment added to attr.Name type.
  - In frontend.Write don't write data to client if error already raised.
  - Always send prompt to client, even if player.PromptStyle is StyleNone, so
    that the text colour is always reset.
  - Set stale attr.Locate,where to nil in Inventory.Remove method.
  - In attr.Inventory.Remove set attr.Locate.Where on Thing removed to nil so
    that we don't end up with a stale reference.
  - The QUIT command should also notify any participant.
  - Extraneous colour resets sent to clients reduced.
  - The attr.Player.Write method no longer modifies the passed []byte and now
    conforms to the io.Writer interface.
  - Green and red balls used as test items removed from zinara.wrj zone file.
  - Added TAVERN qualifier to tavern door in zinara.wrj zone file.
  - Fixed aliases for entrance to the mages tower (L48), Mage's tower (L49),
    entrance to temple (L53), entrance to warrior's barracks (L65) and magic
    shop (L67) in zinara.wrj zone file. Fixed aliases for track near small cave
    (L13) in zinara_south.wrj zone file.
  - The attr.Locate.Copy method should include the origin in the copied data.
  - Fix attr.Thing.SetOrigins method setting origins twice.
  - The attr.Thing.SetOrigins method should include disabled Inventory items.
  - The cmd.junk.dispose method should also dispose of disabled items.
  - Reimplemented Reset.Spawn to fix item respawning nil panics, items not
    resetting due to lost Reset events and duplication of unique items.
  - Fix clean up of Reset event if event not seen and code shortcut taken.
  - In attr.Thing.SetOrigins only set origin for items with a Reset attribute.
  - Fixed data race in cmd.state between cmd.newState and cmd.state.sync methods.
  - attr.Inventory.Move should be able to move disabled items instead of
    silently failing.
  - In junk.lockOrigins lock origins of disabled items.

Known Bugs / Issues

  - If a player is wearing, wielding or holding items and completely log out of
    the server the items will no longer be worn, wielded or held when they log
    back in.
  - Buying and selling are not currently implemented so items at shops, like
    Merkle's Fine Emporium and the Bladesmith's workshop, can just be taken by
    players so they have some items to test the new WEAR, WIELD and HOLD player
    commands.

v0.0.15 Released Thursday 10th November, 2019
==============================================================================

Fixed

  - Typo in data/zones/zinara.wrj for lady in pawn shop.
  - A nil panic in the JUNK command triggered by a location issuing a CLEANUP.

v0.0.14 Released Thursday 31st October, 2019
==============================================================================

Added

  - New ring buffer added for use with connection quotas.
  - Per IP address connection quotas added.
  - A text.Unfold function has been added to unfold folded text while keeping
    significant whitespace.
  - Support added for bound qualifiers allowing a qualifier to only be valid
    for a specific alias. For example: '+SHORT:SWORD SWORD SHORTSWORD' allows
    the item to be referred to as 'SWORD', 'SHORTSWORD' or 'SHORT SWORD' but
    not 'SHORT SHORTSWORD'. The bound to alias does not have to be explicitly
    specified. Given '+SHORT:SWORD' the bound qualifier 'SHORT' will be added
    as will the alias 'SWORD'.
  - Server stats now include number of allocations made since the last stat
    line was logged. Shown in the stats line as 'A[ +n]'.
  - Tests added for GET, DROP, PUT, TAKE, OPEN, CLOSE, EXAMINE, JUNK and READ
    commands.

Changed

  - Cleaned up error handling in client communication code.
  - Documentation updated with HTTPS links.
  - The server greeting and zone file descriptions are now unfolded when the
    record jar file is read.
  - The commands GET, DROP, PUT, TAKE, OPEN, CLOSE, EXAMINE, JUNK and READ now
    use the new matcher code.
  - The messages for the commands GET, DROP, PUT, TAKE, OPEN, CLOSE, EXAMINE,
    JUNK and READ have been improved.
  - Events now use a small cache for timers.
  - Inventories are now implemented using a double linked list instead of a
    slice. This reduces the bookkeeping complexity, storage and allocations.
  - Players and Narratives are now in separate lists within an Inventory.
  - The Inventory.Players method is now Inventory.Occupied to better reflect
    its purpose. Inventory.Players now returns the players in an Inventory.
  - The GET command can no longer be used to pick up another player.
  - The PUT command can no longer be used to put another player into a
    container.
  - The Inventory.Compact configuration value is now obsolete.
  - Matcher code rewritten and performance improved.
  - Action, Cleanup and Reset attribute types now have a Pending method.

Fixed

  - Connection logging now reports correct source file in log.
  - Write timeout for client connections now set correctly.
  - Frontend now delivers outstanding messages to client when closed.
  - Test function TestFixDEL in client tests misnamed, should be TestClean.
  - A gofmt issue in config/config.go has been fixed.
  - Fields within a free text section in a record jar file should just be part
    of the free text section and not recognised as fields.
  - Indented record separators '%%' in a record jar file should be ignored when
    found in a free text section.
  - Line feeds should be preserved when reading record jar free text sections.
  - String lists in a record jar should not be reordered when encoded/decoded.
  - Alias qualifiers are now treated as distinct from aliases. This fixes the
    bug where a qualifier would be recognised as a valid alias.
  - Name of actor for LOOK command should be upper cased.
  - The Thing.Collectable method no longer reports players as being collectable.
  - Corner case in the matcher when switching from 'not enough' to 'unknown'
    match results fixed.
  - Matcher should only be returning unique results.
  - The TAKE command now checks for a TAKEOUT veto before checking if item is
    in the container.
  - For Go 1.13 the server no longer uses command line arguments to set an
    alternative data directory or configuration file. Instead it uses the
    WOLFMUD_DIR environment variable. Documentation compiling-from-source.txt
    and running-the-server.txt have been updated.

Known Bugs

  - New search and matching item limits and item instances undocumented.

v0.0.13 Released Sunday 10th February, 2019
==============================================================================

Security

  - An issue was found that allowed players to send arbitrary data to other
    players via the SAY command. The arbitrary data could contain ANSI escape
    codes and/or other control codes, the effectiveness of which are dependant
    on the capabilities of the player's client. A malicious user could, for
    example: send fake messages, send mock shell screens, ring the terminal
    bell, set the terminal window title. At no time can the malicious player
    obtain any information from other players, all data is still only sent to
    the server. Players receiving potentially malicious data will always see
    the game prompt after the data is sent to them indicating they are still
    logged into the game.

Added

  - New item search and matching code that allows ranges of items, specific
    items and item qualifiers to be used by commands when requiring an item to
    be specified. For example: get all ball, get 2nd ball, get green ball, get
    all green ball, get 2nd green ball.
  - New WHICH command that uses the new item search and matching. Mainly
    intended for players to try out the new search and matching so as to
    provide feedback.
  - New helpers for testing commands provided in cmd/pkg_test.go
  - Tests for WHICH command using new command testing helpers.

Fixed

  - Added missing Start.Free method.
  - Removed stutter from frontend.game methods.
  - Corrected tabbing in v0.0.12 release note entry.

Known Bugs

  - New search and matching item limits and item instances undocumented.
  - Alias qualifiers, aliases with a leading '+' character, have not been
    documented yet.
  - Commands will recognise a qualifier as a valid alias. For example with
    aliases '+GREEN' and 'BALL' commands will see the qualifier '+GREEN' as a
    valid alias. So 'GET +GREEN' would work for the item when it shouldn't.

v0.0.12 Released Sunday 23rd December, 2018
==============================================================================

Added

  - Name attributed gained TheName method for producing better messages.
  - Additional sanity checking added to $CLEANUP command.
  - Zones can be disabled and preventing from loading by using the new DISABLED
    field in the zone header.
  - New quiet.wrj zone added for testing, disabled by default.
  - Barrier attribute allowing creation of conditional barriers preventing
    mobiles from moving in a given direction based on a mobile's aliases.
  - Barriers added to stop mobiles with CREATURE alias from entering certain
    areas in zinara.wrj zone.
  - City guards and gate wardens added to zinara.wrj zone.
  - Shopkeepers (non-functional) added to zinara.wrj zone.
  - Maps added in docs/zone-maps.txt for main, stock zones.
  - attr.Inventory.Everything method added, equivelent to separate Content and
    Narratives calls but more efficient.
  - New ClearOrigins method added to attr.Thing type.
  - Added checks for PUTIN/TAKEOUT pseudo commands for PUT/TAKE command veto
    checking. This allows for one-way containers to be created where you can
    only put things into or take things from a container.

Changed

  - $ACT, DROP, EXAMINE and SAY commands updated to use Name.TheName method.
  - Actor now passed to has.Vetoes.Check method to allow access to additional
    information when processing vetoes.
  - $CLEANUP now finds item based on passed actor instead of alias lookup.
  - In JUNK command cancel any pending Action or Cleanup events earlier.
  - Cleanup outstanding reset check in attr.Reset.Reset method.
  - Actor and item UID now passed to $CLEANUP and $RESET commands.
  - The attr.FindVetoes function has been replaced by attr.FindAllVetoes as all
    sources of vetoes should be considered - not just the first one found.
  - Minor performance gain by checking vetoes only once in MOVE command.
  - MOVE command now checks the location itself and all location items for
    vetoes. Previously it only checked the current location's narratives.
  - The frog, rabbit, spider and cat now have the CREATURE group alias.
  - The barkeep, vendor and flower girl now have the NPC group alias.
  - Fast moving mouse (added for debugging) now penned into dim alley and event
    rate slowed down.
  - attr.Thing.SetOrigins updated to use attr.Inventory.Everything method.
  - zones.checkDoorsHaveOtherSide and zones.isParent updated to use
    attr.Inventory.Everything method.
  - MOVE command updated to use attr.Inventory.Everything method.
  - In attr.Inventory.Disable drop redundant FindLocate and SetWhere calls.
  - Updated attr.Locate.Dump to differentiate between Where/Origin not being
    set and no Name being available - now displays 'Nowhere'/'no name!'
  - DROP improved veto checking, additionally checks item's current inventory.
  - GET improved veto checking, additionally checks receiving inventory.
  - EXAMINE improved veto checking, additionally checks current location.
  - JUNK improved veto checking.
  - Redundant checks in DROP command removed.
  - PUT/TAKE improved veto checking, additionally checks for PUTIN/TAKEOUT
    pseudo commands. PUT/TAKE no longer check for GET/DROP vetoes.

Fixed

  - Data race in zone loader zone.checkDoorsHaveOtherSide function fixed
  - Fixed JUNK command terminating veto checks too early resulting in some
    non-junkable items being junkable under certain conditions.
  - Extra period removed from 'You can see no immediate exits from here'
    message returned by attr.Exits.List method.
  - Added additional bookkeeping to *Inventory.Free method to reset slice
    elements and split and playerCount values.
  - Fixed Player.Check so that players cannot be junked.
  - Fixed reset message not seen if player in a container.
  - Typo ally's/alley's in zinara.wrj zone file.
  - Fixed missing period on TAKE command error message.
  - Fixed panic when mobile uses GET/TAKE via $ACTION without the mobile having
    an inventory defined.
  - attr.Thing.Collectable method should check for nil and typed nil in check.
  - Fix nil panics in $CLEAR, $RESET and JUNK commands by clearing and not
    setting origins in attr.Reset.Spawn method.
  - Data race fixed in zones.linkupZones function.

v0.0.11 Released Tuesday 31st October, 2018
==============================================================================

+++ BREAKING CHANGES +++

  - SYNTAX OF ONACTION CHANGED
    The OnAction field in zone files previously used a list of strings.  When
    the Action fired one of the strings was picked at random and displayed. For
    example, the frog was defined using the old syntax as:

           Ref: M3
          Name: a small frog
         Alias: FROG
         Reset: AFTER→1m
       OnReset: A frog hops into view.
        Action: AFTER→10s JITTER→20s
      OnAction: The frog croaks a bit.
              : The little frog leaps high into the air.
              : The frog hops around a bit.

    With this update OnAction expects a list of commands. The new $ACT command
    can be used in place of the old strings list. However, the $ACT command
    will add the actors name to the beginning of the supplied text.
    Furthermore, if the actor's name starts with 'a ' it will be changed to
    'the ' - as this tends to produce better messages. For example, "$ACT
    croaks a bit." would display "The small frog croaks a bit". The definition
    for the frog using the new syntax, with additional movement commands so the
    frog will wander around, is:

           Ref: M3
          Name: a small frog
         Alias: FROG
         Reset: AFTER→1m
       OnReset: A frog hops into view.
        Action: AFTER→10s JITTER→20s
      OnAction: $ACT croaks a bit.
              : $ACT leaps high into the air.
              : $ACT hops around a bit.
              : N
              : S
              : E
              : W

    The supply zone files have been updated for the new OnAction syntax. User
    supplied or modified zone files will need to be manually updated. Until
    then the strings will be processed, but most likely result in trying to
    execute invalid player or scripting commands.

Added

  - recordjar: new and improved encode/decode tests and benchmarks.
  - New $ACT scripting command for performing actions via Action/OnAction.
  - Barkeep added back into the tavern (in data/zones/zinara.wrj).
  - Flower girl added back outside the pawn shop (in data/zones/zinara.wrj).
  - Giant spider added back into the shed (in data/zones/zinara.wrj).
  - Street vendor added back at crossroads (in data/zones/zinara.wrj).
  - The frog and rabbit (in data/zones/zinara.wrj) now move around from
    location to location.
  - The fireplace in the tavern (in data/zones/zinara.wrj) now has a separate
    fire narrative.
  - Added a fast moving mouse to the tavern (in data/zones/zinara.wrj). This is
    useful for triggering any locking bug or data races quickly in the changed
    Action/OnAction processing.
  - Make sure all players have a  PLAYER alias. Existing players will have the
    alias added when next loaded.

Changed

  - recordjar: package documentation improved.
  - recordjar: encoded StringList and KeyedStringList fields now starts each
    item in the list on its own line.
  - Logging now uses UTC instead of local time zone.
  - recordjar: encode/decode DateTime uses UTC for result.
  - The attr.Description Marshal method now uses encode.Bytes.
  - recordjar: encode and decode now expect date/time values in RFC1123Z. Will
    fallback to RFC1123 to support date/time values in the old format.
  - recordjar: non-exported indexSeparator returns the separator starting index
    and the length of the separator rune found. Previously  returned a bool.
  - recordjar: encode/decode KayedString function dropped.
  - The OnAction attribute now takes a list of commands instead of a list of
    strings to display.

Fixed

  - recordjar: Write method rewritten to clean up code. Fixes issue with
    trailing white space after a field name with no values. Field name are now
    written with consistent ordering.
  - recordjar: encode/decode String trims leading/trailing white space.
  - recordjar: encode/decode Keyword removes ALL white space.
  - recordjar: encode/decode KeywordList orders the list items consistently.
    Any list entries with empty or duplicate field names are dropped.
  - recordjar: encode.PairList removes ALL white space from field names and
    values. List is sorted consistently.
  - recordjar: encode.StringList trims leading/trailing white space from
    values.  List is sorted consistently.
  - recordjar: encode.KeyedStringList removes ALL white space from keys and
    trims leading/trailing white space from values.  List is sorted
    consistently.
  - recordjar: encode/decode Duration rounds seconds (half up).
  - recordjar: encode.KeyedString omit delimiter after field name if no value.
  - recordjar: encode/decode Bytes trims leading/trailing white space up to the
    first/last line feed found.
  - recordjar: decode.Duration strips ALL white space.
  - recordjar: encode/decode PairList will ignore values where no field name
    given.
  - recordjar: decode.DateTime trims leading/trailing white space.
  - event: when event logging is turned on only log events actually cancelled.
  - cmd: Uppercase first letter of speakers name for SAY command.
  - cmd: Uppercase first letter of item examined for EXAMINE command.
  - Nil pointer panic fixed in attr.Alias.SetParent method.
  - Can now use 'Veto' or 'Vetoes' in zone files. Updated provided zone files
    where only one veto defined.
  - Don't stop processing when using the SAY command and there is nobody else
    at the location. Otherwise players in nearby locations will not hear
    someone talking to themself.

v0.0.10 Released Friday 6th July, 2018
==============================================================================

Added

  - Added test in recordjar/read_test.go for duplicate field names.
  - Added tests in recordjar/read_test.go for colons without field names.
  - New configuration option Server.LogClient to enable or disable logging of
    connecting client's IP address on initial connection. Defaults to disabled.
  - New log package for per-connection logging.
  - Log account login.
  - Log account creation.

Changed

  - Improved reporting on which jar test failed in recordjar/read_test.go
  - The comms package now logs using per-connection sequence numbers.
  - Combine writing of "bye bye" and resetting default colours when closing
    connection to client.
  - Switched comms and frontend packages to use new log package.
  - If the new configuration option Server.LogClient is set to false don't leak
    IP addresses via system error messages. Instead replace the 'address:port'
    string with '???' when logging the error.

Fixed

  - Corrected comments in frontend.go to reference closedError instead of
    Error.
  - Fixed panic when empty string passed to text.TitleFirst function.
  - In recordjar/read_test.go reported values for mismatches are reversed.
  - Cleaned up white-space in the default configuration file.

v0.0.9 Released Monday 28th May, 2018
==============================================================================

Added

  - The recordjar.decode.indexSeparator helper function.
  - Boolean values can now be present/absent as well as set to true/false in
    zones files. For example OPEN is the same as OPEN=true, omitting OPEN is
    the same as OPEN=false. Included zone files updated where appropriate.
  - Added StringList, KeyedString and KeyedStringList functions to package
    recordjar/encode.
  - All attributes now implement a Marshal method.
  - Added an attr.Thing.Collectable method.
  - New SAVE command to write player data to player files.
  - Added a collectable bag and sack to the tavern in the Zinara zone for
    testing player saves with containers.
  - Added 'on the fly' resets to cmd.junk.dispose method so that items without
    a reset specified can be forcibly reset.
  - Added recordjar.decode.DateTime function.
  - Added frontend.login.assemblePlayer to build a player from a recordjar.Jar.
  - New attr.Gender attribute.
  - New text.Uncomment function to remove comments embedded in strings. For
    example in regular expressions commented like Perl's /x modifier.
  - Commented recordjar.splitLine regular expression and added tests.
  - New attr.Thing.NotUnique method to mark a Thing as non-unique when building
    temporary stores - when loading zone and player record jar files (*.wrj).

Changed

  - Improved reporting of unknown attributes when loading zone/player files.
  - The recordjar/decode functions PairList and StringList now return a
    map[string]string instead of [][2]string.
  - The recordjar/encode PairList now takes a map[string]string and rune
    delimiter instead of [][2]string and a string delimiter.
  - The recordjar/decode function KeyedString now returns name and value
    strings instead of a [2]string array.
  - Cleaned up the KeyedString and PairList functions in recordjar/decode.
  - attr.Attribute.Marshal now returns a tag string and []byte data.
  - The QUIT command now saves players. Any non-collectable items are disposed
    of and reset.
  - Added account information to attr.Player so that an account header record
    can be written to the player file when saving the player.
  - frontend.login.passwordProcess now uses frontend.login.assemblePlayer.
  - Updated frontend.account.write to build a new player using attr.* types.
    Resulting new player file is written using the new SAVE command.
  - recordjar.Read reimplemented for clarity.
  - recordjar_test.compareJar helper rewritten and renamed compare.
  - Tests for recordjar.Jar.Write rewritten, cleaned up and improved.
  - Temporary attr.Attribute.Marshal method used in development dropped.

Fixed

  - The recordjar.Jar.Write now wraps long lines to 80 characters and
    title-cases field names.
  - In attr.Thing.SetOrigin drop redundant Inventory lookup.
  - recordjar.Jar.Write no long writes an extra leading space before a field
    name.
  - recordjar.Jar.Write now normalises field names.
  - recordjar.encode.Duration now omits trailing zero units.
  - Added missing colon to Name and Description attributes in DUMP command.
  - All package comments now start with 'Package X...'.

v0.0.8 Released Tuesday 31st October, 2017
==============================================================================

Added

  - The Reset attribute now has an Abort method to cancel reset events.
  - New player zone, Zinara Caves - was the newbie zone in the Java version.

Changed

  - The exits.Within method now take an additional has.Inventory parameter. See
    fixes below for details.
  - Command handlers are now types instead of simple functions.
  - Implementation of JUNK command cleaned up.
  - The VERSION command now includes the version of the compiler used.
  - The handler for the empty command is now in its own cmd/cmd.go file.
  - The state.handleCommand method has been moved to the handler.go file.
  - The cmd package no longer exports the AddHandler function.
  - If something is in the game it is always somewhere. Therefore, we can drop
    redundant checks of where we are from command processing.
  - Logic for removing events has been dropped from the Inventory attribute and
    moved to the GET and TAKE commands. This means the logic does not have to
    processed every time a Thing is moved - only when the GET or TAKE commands
    are used. It also removes a lot of 'magic' from the Inventory code.
  - Logic for adding events has been dropped from the Inventory attribute and
    moved to the DROP and PUT commands. This means the logic does not have to
    processed every time a Thing is moved - only when the DROP or PUT commands
    are used. It also removes a lot of 'magic' from the Inventory code.
  - The JUNK command no longer has to deal with the weird issue of handling
    copies that are spawned when junking a respawnable Thing.
  - The Inventory.Move method no longer checks if a Thing has a Locate
    attribute. This is now only done when a Thing is first added to an
    Inventory.
  - The Inventory Move method no longer returns a Thing.
  - The player count is now included in the DUMP information for an Inventory.
  - The Inventory Add and Remove methods now add and remove Thing to or from
    the Inventory disabled list. The AddDisabled method has been dropped.
  - Split RecordJar encoder/decode in own sub-packages.

Fixed

  - Made exits.Within work as expected/intended. The first returned slice
    should always be the current location. If the current location had no exits
    the parent could not be determined to find the current location so it was
    not populated in the returned slice. As a result the exits.Within method
    now takes an additional has.Inventory parameter for the current location.
  - The Inventory attribute Copy and Free methods should also process Thing in
    the disabled list.
  - The JUNK command should cancel action events and the $RESET command
    re-enable them.
  - The JUNK command should cancel active Cleanup events.
  - Fix Thing spawn check in GET and TAKE commands which prevented Thing
    without a Reset attribute from being taken, even though on screen messages
    indicate success.
  - Fix data race cause by zone loader not locking Inventory attributes while
    manipulating them.

v0.0.7 Released Sunday 10th September, 2017
==============================================================================

Added

  - New Inventory.Outermost method to find the top most Inventory in an
    Inventory hierarchy.
  - New CONTRIBUTORS, CONTRIBUTING and DVO (Developer's Certificate of Origin)
    files added.
  - A Thing in an Inventory can now be taken out of play (disabled) and put
    back into play (enabled). This is the main mechanism used to avoid data
    races when an item resets or respawns as it allows the item to be locked
    via a BRL even when out of play.

Changed

  - Rewritten #DEBUG command.
  - Dropped remaining references to Server.Debug configuration value.
  - Make Locate attribute concurrent safe - fixes data race.
  - Make Thing attributes concurrent safe - fixes data race.
  - Updated sources to use idiomatic standard libraries imported first.
  - Updated sources to use idiomatic 'Mutex hat' style in types.
  - cmd.state.AddLock and cmd.state.CanLock automatically always lock the BRL
    for the top most Inventory in a hierarchy.
  - Performance improvement in comms.fixDEL for 'character at a time' Telnet
    clients.
  - Thing.SetOrigins updated to include disabled items in an Inventory.

Fixed

  - Ignore incomplete/broken pairs when unmarshaling recordjar.
  - Default clean up message now displayed when appropriate.
  - Thing.Remove sets attribute parent to nil.
  - Fixed scripting of JUNK command usage in CLEANUP command.
  - Fixed data race resetting Player prompt in QUIT command.
  - Fixed data race in SNEEZE command.
  - Fixed data race when initially adding player into the world.
  - Using delete key on 'character at a time' Telnet connections no longer
    causes an array index out of bounds error.
  - When using delete key on 'character at a time' Telnet connections
    multi-byte Unicode characters are now handled correctly.
  - A nil *message.Buffer no longer causes a nil pointer error.
  - Accessing the Attribute type parent methods is now concurrent safe - fixed
    data race.
  - Resetting and respawning of items now uses Inventory item enabling and
    disabling - fixes data races.
  - Reworked JUNK command - fixes data races.
  - Only set file permissions on created files when operating system and file
    system permits. This fixes an issues on Windows preventing user logging in
    to the server after creating a new account.


v0.0.6 Released Sunday 1st May, 2017
==============================================================================

Security

  - Tighten permissions on new player files and file produced by the #DEBUG
    command. It is adviseable to run chmod 0660 data/players/*.wrj on Linux. On
    Windows please review the file permissions for existing files.
    Commit: da2ed6b and eefef4b.

  - Reduce the amount of time plain text passwords are held in memory. Some
    player passwords may have been compromised due to use of the #DUMP command
    and access to the heapdump file. Some player passwords may have been
    compromised if local users can access the server's memory.
    Commit: b29e762.

Added

  - New OnCleanup attribute for custom clean up messages, see
    docs/zone-files.txt for more details.
  - New OnReset attribute for reset/respawning up messages, , see
    docs/zone-files.txt for more details.
  - New OnAction and Action attributes, see docs/zone-files.txt for more
    details.
  - Inventories have a new Players method for checking if there are any players
    in an inventory.
  - New #DEBUG command to aid developing and debugging.

Changed

  - Output of READ command made more generic. Instead of the template being
    "You read the writing on <item>. It says: <writing>" it is now "You read
    <item>.  <writing>".  Wording of WRITING attributes in zone files may need
    updating.
  - If a reset or respawn occurs within a container and an OnReset message is
    provided the message will propagate to the location the container is in.
  - Zone files updated with OnCleanup and OnReset messages.
  - Prevention of players being junked now via automatic veto.
  - Statistics in log now display a Thing count.
  - Lease acquired and released messages no longer reported in log.
  - Improved debugging flags in config.wrj, see docs/configuration-file.txt for
    more details.
  - Event goroutines now recover from a panic unless Debug.Panic is true. See
    docs/configuration-file.txt for more details.

Fixed

  - The LOOK command now automatically uppercases the first letter in titles.
  - The TAKE command now automatically uppercases the first letter of a
    container's name.
  - Improved layout of event.Cancel in #DUMP output.
  - The #DUMP command no longer crashes the server with invalid addresses.


v0.0.5 Released Sunday 2nd April, 2017
==============================================================================

Added

  - Events gained jitter to introduce randomness to timing.
  - New mechanism added to better free and release resources for garbage
    collection.
  - New Inventory.Move method more efficient for the common case of moving
    something from one Inventory to another. Add and Remove methods updated to
    use Move. Commands updated to use new Move where possible.
  - Added automated resets and spawning to items via new Reset attribute.
  - New $RESET and $SPAWN scripting commands.
  - New JUNK commands for player to dispose of items.
  - Added automated clean ups to items via new Cleanup attribute.
  - When debugging the DUMP command can now take the address of a Thing.
  - New unique ID generator - all Thing now have a unique ID and unique alias.

Changed

  - Added jitter to Door attributes to add some randomness.
  - Inventory now add a Locate attribute to a Thing when it is put into an
    Inventory.
  - Zone loader rewritten and improved.
  - Reported memory stats in the log are now more accurate.
  - Buffers in the message package reworked to be more efficient with the
    addition of a reusable pool of buffers.
  - Exits.List method improved to create less garbage and use less string
    concatenation.
  - Updated items in zones with new Reset attribute.
  - Updated items in zones with new Cleanup attribute.
  - Inventories where the parent Thing has a narrative attribute no longer
    display 'It is empty' when there are no non-narrative content.

Fixed

  - Doors can now be placed between zone where on side is in one zone and the
    'other side' is in a different zone.
  - References are now properly released from slices fixing a minor memory
    leak.
  - Fixed a panic when calling Player.Close on a nil Player pointer. In reality
    not a big issue as it was triggered when the player logged out and didn't
    crash the server unless running in debug mode.
  - Fixed decoder.Duration in recordjar package so that it can parse uppercased
    data passed to it.

Known bugs

  - When using the DUMP command with memory addresses it's to easy to crash the
    client thread. Comments have been added warning of this and DUMP with a
    memory address is only enabled when the server is run in debug mode.


v0.0.4 Released Thursday 2nd March, 2017
==============================================================================

Added

  - Test cases added for rewritten recordjar.Read method.
  - New recordjar data types: StringList, KeyedString, KeyedStringList. See
    docs/zone-files.txt for details.
  - Zone files can now contain vetoes.
  - cmd.state has a new Script method for scripting commands. Commands only
    usable in scripting mode denoted by prefixing the command with a '$'
    symbol.
  - New script only $POOF command to announce players joining game.
  - attr.Inventory gained a Narratives method to retrieve narrative items.
  - new event package for asynchronous scripted commands.
  - text package gained a new TitleFirst method to uppercase the dirst rune in
    a string.
  - All attributes and attr.Thing now have a Copy method. The Copy method has
    also been added to the has.Attribute and has.Thing interfaces.
  - New Door attribute added so that doors can be defined in zone files. See
    docs/zone-files.txt for details.
  - Added the tavern door and shed door to data/zones/zinara.wrj as example
    doors.
  - New OPEN and CLOSE commands to open and close doors.

Changed

  - Rewritten recordjar.Read method to be simpler and have fewer corner cases.
  - EXAMINE command can now be vetoed.
  - zones package now adds a Locate attribute to Things with a Door attribute.
  - zones package now creates the 'other side' of doors when a Thing has a Door
    attribute.
  - Update COMMANDS command to not report scripting only commands starting with
    a '$' symbol.
  - MOVE command can now be vetoed.

Fixed

  - Another colour bleeding issue fixed.
  - Nil panic fixed when loading zones and populating inventories with an
    invalid ref.
  - Passing of a copied mutex in text.Dictionary.
  - recordjar.decoder should uppercase returned key and data as documented.
  - attr.inventory Add method should always call SetWhere if Locate attribute
    is found.

Known bugs

  - Adding a Door attribute to a non-narrative, e.g. directly to a location or
    a moveable item, can result in strange and unexpected behaviour.
  - The new Thing and Attribute copy mechanism does not check for cyclic
    dependencies.

v0.0.3 Released Friday 23rd December, 2016
==============================================================================

Fixed

  - Colour bleeding issues fixed (Mainly Windows TELNET)
  - Multiple description sequence fixed so that main descriptions come first.


v0.0.2 Released Monday 5th December, 2016
==============================================================================

Added

  - Text folding now has support for Unicode combining characters.
  - Added NONE as a runtime option to not load any configuration file.
    See docs/running-the-server.txt for details.
  - New messages package containing message buffers.
  - Message buffers now support a silent mode.
  - Commands now send coloured messages:
      - Red: Something bad / undesirable happened
      - Green: Something good / desirable happened
      - Yellow: Something informational happened
  - Server greeting can now contain embeded colour codes.
  - Added initial tests for text and message packages.
  - New docs/upgrading.txt

Changed

  - Improved performance of embedded colour codes.
  - text.Dictionary map now protected by sync.Mutex.
  - Message buffers moved from cmd/state to new message package.
  - Message buffers reimplemented, no longer based on bytes.Buffer.
  - Message buffers now use Send and Append methods instead of WriteJoin.
  - cmd/state and frontend both use new message package for buffers.
  - state.script method uses new message buffers.

Fixed

  - Fixed an issue with TELNET clients sending unprocessed strings containing
    DEL (ASCII 0x7F or \b) characters. Using delete in Windows TELNET client
    now works as expected.
  - Text folding should only preserve leading whitespace.
  - Fixed a panic in text.Fold with a width less than 1.
  - Fixed a panic if player only enters stop words.

Known bugs

  - An extra blank line is sometimes appended to the end of the greeting
    displayed when players connect. This seems to be an issue in the recordjar
    package.
  - If Send or Append is used to start a message and only a colour is written a
    subsequent Append will cause a space to be present at the start of the
    message.

Security

  - None :)


v0.0.1 Released Monday 31st October, 2016
==============================================================================

  Initial release.
