                             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.20 Released Thursday 30th June, 2022
==============================================================================

Added

  - New state.Log method added for commands to log with actor's UID prefix.
  - New Opponents anyKey+anyName and Opponent refKey+refName in core/types.go
  - New Combat events with basic combat event handler.
  - New ATTACK command added to initiate combat. KILL is an alias for ATTACK.
  - New term package for controlling the client terminal.
  - New client.eat method to consume pending incoming data.
  - Added StatusSeq asKey and asName to core/types.go for storing the ANSI
    escape sequence to update the terminal status line.
  - New state.StatusUpdate method to update terminal status line via mailbox.

Changed

  - Source code for HIT command moved to core/combat.go
  - Improved corpse descriptions.
  - QUIT command updated to terminate combat.
  - MOVE command updated to prevent combatants walking off when fighting.
  - LOOK command now indicates combat at a location.
  - Previous HIT command code removed and HIT aliased to ATTACK.
  - Action events are not rescheduled if an action initiates combat.
  - Updated core.client type to hold terminal width, height and ANSI escape
    sequences.
  - Text sent to the client is now folded using the terminal width minus 2
    characters - Windows TELNET draws a scroll bar over the last two characters
    on a line :(
  - Prompt handling code has been removed, replaced by a status line.
  - The mailbox suffix handling is no longer required and has been removed.
  - There is no longer a need to nudge the actor off the prompt line in the
    QUIT and $HEALTH commands.
  - BotRunner updated to work with new terminal handling.

Fixed

  - Thing.suspend returns false on failure to suspend due to stale event.
  - When an event firesThing.schedule checks if the event was cancelled while
    waiting to acquire BRL.
  - Thing.schedule should only schedule future events when using dueIn.
  - Mobiles/NPC now reset will full health.
  - TELL/TALK and WHISPER commands improved when actor targets themself.
  - Added crowd control to health event messages.
  - Resetting of item usage moved from state.Quit and state.quitUniqueCheck to
    Thing.Junk where it makes more sense.
  - Body parts are no longer lost when quitting while using a unique item.

v0.0.19 Released Sunday 24th April, 2022
==============================================================================

    WolfMUD v0.0.19 is a 90%+ rewrite of WolfMUD v0.0.18. Compatibility with
    existing zone files and player files has been maintained. While these
    release notes try to highlight differences between the two versions, see
    the release notes for the v0.0.19 betas below for more details.

    Every effort has been made to implement the features and functionality that
    was previously available in v0.0.18. These release notes serve to document
    any differences and additions in the v0.0.19 release.

    The only change between v0.0.19 and v0.0.19-beta.6 are the release notes
    and a tidy-up/clarafication of the build descriptions.

Upgrading Notes

  - In data/config.wrj, Inventory.CrowdSize is now the minimum number of
    players to be considered a crowd. Before it was the number of players
    before they where considered a crowd. The default value has changed from 10
    to 11 - 11 or more players is a crowd. See docs/configuration-file.txt for
    more details.
  - In data/config.wrj, a separate login timeout has been added: Login.Timeout
    with a default value of 1m - 1 minute. See docs/configuration-file.txt for
    more details.
  - Per IP address connection quotas have been simplified. In data/config.wrj
    Quota.Timeout and Quota.Stats are no longer used. A new Quota.Slots
    configuration value has been added, which defaults to 0. Quotas now allow
    up to Quota.Slots connections per Quota.Window per IP address. There are no
    quote statistics, however there is a new Debug.Quota flag which provides
    some additional information. See docs/configuration-file.txt for more
    details.
  - In zone and player files the Health field attributes have changed from:

      [Old format]  Health: FREQUENCY→     CURRENT→ MAXIMUM→ REGENERATES→
      [New format]  Health: AFTER→ JITTER→ CURRENT→ MAXIMUM→ RESTORE→

    FREQUENCY has been replaced with AFTER+JITTER to bring Health in line with
    other events. REGENERATES has been replaced with RESTORE as it is more
    generic and can be reused on other similar fields. Existing player files
    will be upgraded.  See docs/zone-files.txt for more details. Zone files
    should be reviewed and mobiles/NPCs updated as necessary.
  - Players now have a new Permissions field. This can contain the value
    'ADMIN' which grants access to all admin commands. Alternatively, access
    can be granted to specific admin commands only by listing the specific
    commands. For example:

      Permissions: ADMIN
      Permissions: #DUMP #GOTO

    Per player permissions replace the Debug.AllowDump and Debug.AllowDebug
    settings in data/config.wrj, which are removed. See the ADMINISTRATORS
    section in docs/running-the-server.txt for more details.

Added

  - Linux ARM64 is now officially supported with pre-built downloads available.
  - The matcher now understands 'SELF'. For example: EXAMINE SELF, HIT SELF.
  - The matcher now understands 'MY' to refer to items in your own inventory.
    For example: EXAMINE MY SWORD, PUT APPLE MY BAG.
  - The matcher now understands 'ANY' to refer to a random item when there are
    multiple matches. For example: GET ANY APPLE, WIELD ANY SWORD.
  - Duplicate messages sent to players are de-spammed so that fewer duplicates
    will be seen.
  - Imps and fungus slugs have been added to zinara_caves.wrj, the "Caves near
    Zinara" zone.
  - There are now corpses when the HIT command is used to kill something.
  - A new /WHOAMI command has been added in case you forget which character is
    logged in on which terminal.
  - Zone and player files are now more Unicode friendly, including REF/@refs.
  - Players now have a command history for up to thee previous three commands.
    The history can be shown using /HISTORY or the abbreviation '/!'. Commands
    can be replayed from the history using '!', '!!' and '!!!' respectively.

Changed

  - The output for the #DUMP/#LDUMP commands have been updated to reflect how
    items are stored internally. There is no Unicode #UDUMP variant yet.
  - The #DUMP/#LDUMP commands can accept '@' to dump everything in the current
    location - mnemonic is where you are 'at'. For example: #DUMP @
  - New server statistics: A[n] O[n ±n] T[n ±n] E[n ±n] P[n max]

      A[    n] - runtime allocations since last collection
      O[n  ±n] - runtime objects / change since last collection
      T[n  ±n] - Thing in the world / change since last collection
      E[n  ±n] - in-flight active events / change since last collection
      P[n max] - current number of players / maximum number of players

  - In zone and player files the leading '+' for bound qualifiers only may be
    omitted. For example, SHORT:SWORD and +SHORT:SWORD are equivalent - but the
    latter is preferred for consistency with non-bound qualifiers.
  - Player names are now restricted to 15 characters during account creation.
  - A mobile/NPC is now defined as anything that can self heal. Existing zone
    files should be checked to make sure mobiles/NPCs, that are intended to be
    mobiles/NPCs, have a Health record with at least MAXIMUM, RESTORE and
    AFTER/JITTER attributes set.
  - The /PROMPT command now has five styles:
      NONE
      CURSOR  >
      BRIEF   H:30>
      SHORT   H:25/30>
      LONG    Health: 25/30>
    The prompt does not currently colour current health based on percentage of
    maximum health yet.
  - The server no longer logs client connections and disconnections, unless
    client IP addresses are being logged - Server.LogClient is set true. The
    server will log player logins and players quitting:
      [#UID-F] Login by: 16809599915800bb7a67d231daef3b9f
      [#UID-F] Quitting: 16809599915800bb7a67d231daef3b9f
  - The stock zones in data/zones have had many improvements and bug fixes.

v0.0.19-beta.6 Released Sunday 17th April, 2022
==============================================================================

Security

  - Limit input data from client (potential DOS attack mitigation).

    Currently no limits are put on the length of a command a player can send to
    the server. As the input is stored in a []byte buffer, a malicious client
    could cause the buffer to consume a lot of the memory. This could be used
    as a DOS attack - this has not been seen in the wild and has not actually
    been exploitable during testing.

    The server now limits the size of the input accepted by the server. If a
    client sends a command longer than the limit to the server then all of the
    input is discarded and the message "You type too much!" is sent to the
    client. The current input limit is 80 bytes.

Added

  - New /PROMPT player command to check, list and change prompts.
  - New core/state.Script method for executing scripting commands outside of
    the core package.
  - Per-player permissions can be set via a new Permissions field in the player
    header record. Currently permissions can be 'ADMIN' or a specific admin
    command. Admin commands are those prefixed with a hash '#'. Details for
    setting up administrators added to docs/running-the-server.txt
  - Player command history and recall for up to three commands added. The last
    three commands can be listed using '/HISTORY' or the abbreviation '/!'. The
    last three commands can be repeated using '!', '!!' and '!!!' respectively.
  - ARM64 built target added to makefiles and release builds.
  - New data/zones/quiet.wrj zone for testing in isolation, defaults disabled.

Changed

  - The player's prompt is now selectable and perists in the player file. The
    available prompts are: NONE, CURSOR, BRIEF, SHORT, LONG.
  - The Debug.AllowDump and Debug.AllowDebug options have been dropped from the
    server configuration and have been replaced by per-player permissions.
  - The #DUMP/#LDUMP commands now show Int values as data/time or durations
    where appropriate.
  - In data/zones/zinara.wrj make curious brass lattice a little more curious.

Fixed

  - Health events are now registered for mobiles / NPCs when they are loaded,
    if they need healing.
  - Health events are now registered for mobiles / NPCs when they are junked,
    if they need healing.
  - Events for anything junked are now suspended and resumed if a reset occurs,
    as opposed to the thing being disposed of.
  - The "... kills you ..." message from the HIT command correctly upper-cases
    then name of what kills you.
  - Players can no longer directly execute scripting commands with a dollar '$'
    prefix.
  - OnAction fixed for ugly imp in data/zones/zinara_caves.wrj
  - Store player created date in Thing.Int[CREATED] as nanoseconds.
  - Event dueAt timestamp now shown in UTC to match server logging.
  - Don't log player connects and disconnects if not logging client IP address.
  - Log when a player quits - either willingly or unwillingly (due to errors).
  - In data/zones/reset.wrj drop invalid O9 reference and add item clean-up.

v0.0.19-beta.5 Released Sunday 27th March, 2022
==============================================================================

Added

  - The matcher package has a new trimMatch function to remove leading
    stopwords, modifiers, qualifiers and alias from an original input that
    would have been used in a match.
  - New TELL/TALK player command.
  - New WHISPER player command.
  - New map of in-game players added to core.state, players added by $POOF and
    removed by QUIT command.
  - New /WHO command to list other players currently in-game.
  - New /WHOAMI command to remind yourself who you are.
  - New Thing.selfHeals helper method.
  - Mobiles/NPCs that are holdable can no longer be PUT into containers.

Changed

  - The bots from the botrunner now TELL/TALK and WHISPER again.
  - The data/zones/zinara.wrj zone file has been updated so that some NPCs will
    directly address the player.
  - Clean-up initial section, example zone file, field data types and @refs
    section in docs/zone-files.txt
  - Clean-up EXIT/EXITS entry in docs/zone-files.txt
  - When unmarshaling a Thing current health is only set to maximum health if
    current health is zero and Thing can self heal.
  - An NPC is now anything that can self heal.
  - Updated docs/zone-files.txt for self healing and mobiles/NPC.
  - Updated data/zones/zinara.wrj to make sure all NPCs have Health so that
    they behave properly.
  - Documentation for KEYWORD and REF sections in docs/zone-files.txt has been
    updated and improved. REF section now has examples of naming schemes.
  - Documentation for NAME section in docs/zone-files.txt expanded and contains
    details of 'a/as/some' to 'the' and upper/lower case conversions.
  - Corrected who can see messages in CLEANUP section of docs/zone-files.txt

Fixed

  - Delete Thing.Event map entries for suspended events.
  - Suspend events scheduled by InitOnce/Init if Thing loaded disabled with a
    suspended reset event.
  - The maximum length of player names is now 15 letters. Previously no limit.
  - Initialise World in core.state where it is defined, not world.Load.
  - The SOME qualifier usage has been dropped from data/zones/zinara.wrj as it
    will never match due to being dropped as a stop word.
  - Improve some alias qualifiers in data/zones/zinara.wrj
  - Fix nil panic when DOOR attribute used in a location's definition. The
    DOOR attribute is now ignored.
  - Fix body checks failing when all body slots a used for held, worn or
    wielded items.
  - Fix nil panic in REMOVE command when item to remove not found.
  - Drop redundant check for "where.Is&(NPC|Player) != 0" in state.Take method.
  - Added health to the core.preferredOrdering list in core/types.go
  - Implement the minimum one second event period when ACTION, CLEANUP or RESET
    are specified but AFTER, JITTER and DUE_IN are not defined as documented in
    docs/zone-files.txt
  - The world loader now correctly uppercases REFs in zone files. Previously a
    lowercased REF would fail to match when used in, for example INVENTORY or
    LOCATION fields.
  - The pre-processor now identifies @refs with with Unicode letters correctly.
  - Fixed sentance not ending with a period for DROP command.
  - Fixed sentance not ending with a period for GET command.
  - Don't register redundant event when unmarshaling a DOOR field.
  - Type fixed in message for MOVE command.

Known Bugs / Issues

  - If a mobile is loaded with current health < maximum health a health event
    is not registered to regenerate health.
  - If a mobile is holdable and junked when current health < maximum health a
    health event is not registered to regenerate health when mobile resets.
  - If a door is saved and reloaded its reset event is not suspended and
    restored.

v0.0.19-beta.4 Released Sunday 27th February, 2022
==============================================================================

IMPORTANT FILE CHANGES

  Configuration file changes:

    - The Quota section has dropped Quota.Timeout and now uses Quota.Slots
    - The Debug section has a new Debug.Quota

  Server owners should check their data/config.wrj configuration files, details
  of the new fields can be found in docs/configuration-file.txt

  Zone and player file changes:

    - The Health record now uses AFTER/JITTER instead of FREQUENCY to bring it
      in line with other events.
    - The Health record now uses RESTORE instead of REGENERATES.

  Player files will be automatically upgraded. Details on the Health field can
  be found in docs/zone-files.txt

Added

  - New Thing.logEvent helper added. Updated documented Debug.Events flag in
    docs/configuration-file.txt as the events logged have changed from queued,
    cancelled or delivered to scheduled, suspended, cancelled or delivered.
  - Event logging added for Thing Schedule/Suspend/Cancel events.
  - Per IP address quotas are now implemented. These are configured via the
    Quota.Slots and Quota.Window configuration settings in the data/config.wrj
    file. The Quota.Timeout setting is no longer used. The documentation in
    docs/configuration-file.txt has been updated.
  - A new Debug.Quota setting has been added to data/config.wrj to write quota
    debugging information to the server log. For details see Debug.Quota in the
    data/config.wrj documentation.
  - The #DEBUG command with MEMPROF, CPUPROF and PANIC sub-commands is now
    implemented. The configuration Debug.AllowDebug needs to be set to true in
    data/config.wrj to enable the #DEBUG command.
  - New state.subparseFor method to allow commands to perform sub-commands for
    an alternative actor.
  - New Health attribute added for players and NPCs. Existing player files will
    be upgraded when the player next logs in. Updated docs/zone-files.txt to
    document new Health field.
  - Health events, via a new $HEALTH command, have been added for players and
    NPCs to regenerate Health.
  - The build/newAcct script now creates accounts with HEALTH defined.
  - New state.build method to construct dynamic prompts.
  - New core.createCorpse function to create corpses of killed players/NPCs.
  - New HIT command for testing Health, Health regeneration and a bit of fun.
  - The matcher now has an ANY modifier to pick a random match for commands.
  - Added #LDUMP command to write the dump output of a Thing to the server log.
  - Imps and fungus slug mobiles added to the caves zone zones/zinara_caves.wrj

Changed

  - The Thing Schedule, Cancel and Suspend methods are now wrappers to new
    schedule, cancel and suspend methods to enable event logging.
  - The state.Prompt method now takes fmt.Printf like parameters.
  - All messages sent to a specific player are now flagged priority.
  - In data/zones/zinara.wrj the frog, rabbit, mouse and cat have been updated
    with a Health field. A 'HIT ANY PLAYER' action has been added to the frog
    and rabbit.
  - In data/zones/zinara.wrj 'the barkeep' is now 'a barkeep'.
  - The bots now have "HIT ANY CREATURE" and "HIT ANY PLAYER" actions.
  - The mailbox now stores the maphash of the last message seen instead of the
    whole string of the message.
  - Improved messages for TAKE/GET responses when used on players and NPCs.
  - Allow leading '+' to be omitted from bound qualifiers in zone files.
  - Updated actions in data/zones/zinara.wrj that target players to use ANY
    modifier to target a random player.
  - White-space clean-up in data/zones/zinara_caves.wrj
  - Tidy up Debug flag section in docs/configuration-file.txt

Fixed

  - The Thing.Event entry for an event is cleaned up if the event is cancelled.
  - Server now enforces the Server.MaxPlayers configuration setting and will
    turn away players if the server is full.
  - The server now honours the Server.LogClient setting. If set to false, the
    default, the client's IP address will not be logged. Instead the client IP
    address will be replaced with '???'. For example:

      [#UID-6] connection from: ???:35848
      [#UID-6] client error: read tcp 127.0.0.1:4001->???:35848: i/o timeout
      [#UID-6] disconnect from: ???:35848

  - In docs/configuration-file.txt note that Server.Host may be left blank to
    cause the server to listen on all available interfaces.
  - The #GOTO/#TELEPORT command has been fixed.
  - The mailbox.Suffix method no longer panics if the mailbox is invalid.
  - A data race has been fixed when a player quits and is disposed of.
  - The COMBAT veto is now handled by the Thing.Unmarshal and Thing.Marshal
    methods.
  - The Thing.Schedule method now handles stale events when they fire.
  - The build/newAcct script now creates accounts with a BODY defined.
  - The Thing.Junk and Thing.Free methods now cancel in-flight events.
  - Minor grammar fix in zone-files.txt documentation.
  - Fixed confusion of players and NPC/Player flags not working properly.
  - Fixed TAKE/PUT command messages when used on a player.

v0.0.19-beta.3 Released Friday 24th December, 2021
==============================================================================

Added

  - New config package to load the server configuration. Configuration is
    coordinated by the main method, which also configures the packages. The
    package configuration, while not idea does allow packages to be configured
    differently for the testing framework.
  - New stats package for runtime statistics logging. Statistics are
    coordinated from the server main package
  - core.Thing now records Thing and Event counts for statistics reporting.
  - Added a panic handler to the client.receive method. Panic handler is
    configured via the Debug.Panic setting in the server configuration.

Changed

  - All setup locking is now coordinated through the server main method instead
    of separately in world.Load and core.RegisterCommandHandlers functions.
  - Client creation has been split into client.New to create the client and
    client.Play to run the client.
  - The core, world, client and stats packages now have package configuration.
  - The #DUMP command availability is now configured via Debug.AllowDump in the
    server configuration.
  - Enable Thing debug logging showing when Thing created, freed and finalised.
    Configured via Debug.Things in the server configuration.

Fixed

  - The client.assemblePlayer method now frees temporary Thing via Thing.Free.

v0.0.19-beta.2 Released Wednesday 17th November, 2021
==============================================================================

Added

  - Barriers are now implemented to restrict mobiles to a certain area or to
    prevent mobiles going into a certain area. This implementation accepts only
    setting ALLOW or DENY aliases.
  - A suffix, that is appended to sent messages, can now be set for mailboxes.
  - Stop word removal has been implemented. The current sto words are: A, AN,
    FROM, IN, INTO, OF, OUT, SOME, THE, TO and WITH.

Changed

  - Updated docs/zone-files.txt documentation for barriers with clarifications.
  - The #DUMP command now looks for items at a location, then items carried by
    the actor. To specifically look at items carried by the actor the 'MY'
    qualifier can be used.
  - The internal implementation of mailboxes has been cleaned up with a new
    mailbox type.
  - The player's prompt is now implemented using the new mailbox suffix. This
    sets the groundwork for dynamic prompts that can display player statistics.
  - The player's display for the front-end and entering/exiting the game has
    been cleaned up.

Fixed

  - An issue where failed lookups returned a zero value that also mapped to a
    valid key has been fixed. For example if NameToDir[item.As[Blocker]] failed
    it would return the zero value, which is mapped to the constant for North.
    Failed lookups will now result in a "bad key" where appropriate: BadAsKey,
    BadAnyKey, BadIntKey or BadRefKey.
  - Notifications for the OPEN and CLOSE commands have been fixed.
  - Corrected typo in function name, core.conatins -> core.contains

Known Bugs / Issues

  - 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.

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.
