Up to Main Index                         Up to Journal for September, 2020

                   JOURNAL FOR SUNDAY 27TH SEPTEMBER, 2020
______________________________________________________________________________

SUBJECT: Some deliberations on wielding, wearing and holding items
   DATE: Sun 27 Sep 19:24:00 BST 2020

Real life is still really busy at the moment, but I have managed to spend a
little time on WolfMUD. Specifically I’ve been looking at saving and restoring
the state — held, worn or wielded — of items that players have. Yes, I was
going to look at sorting out the attribute system first, but in the end this
seemed more important.

What follows are some notes and details as I work through some issues and make
a few decisions. Some readers like the nitty-gritty details, some don’t.

My first thought was to write out a field for holding, wearing and wielding
into the player header record. A (partial) example:

  %%
      Ref: #UID-1
     Name: Diddymus
  Aliases: DIDDYMUS PLAYER
     Body: HAND→2 …
  Holding: #UID-2
         :
         :
  %%
      Ref: #UID-2
     Name: a spoon
  Aliases: SPOON
         :
         :
  %%

Seems simple enough. We read the first record and find a Holding field, which
has a reference to the item being held — in this case #UID-2. We hold the item
which is then allocated to one of the HAND slots on the Body.

The first problem here is that when a field is unmarshaled into an attribute
the parent is not initially set — so calling Parent() returns nil. This means
that when unmarshaling a Holding field we cannot access the Body attribute by
calling attr.FindBody as we normally would.

The other issue is we don’t know which order the fields will be unmarshaled
in, not only can the records be hand edited and in any order, but the fields
for a record jar are held in a Go map. Therefore we could unmarshal the Body
then Holding or Holding then Body. If it’s the latter then there would be no
Body yet for Holding to find via attr.FindBody anyway.

Hrm…

I circumvented that by adding an optional PostUnmarshal method to attributes.
After assembling a Thing, by unmarshaling the attributes, Thing checks the
attributes to see if any have a PostUnmarshal to call. In this way the Holding
attribute can implement a PostUnmarshal and have access to all of a Thing’s
attributes, including Body.

However, there is another issue. When an item is saved the current unique ids,
#UID-1 and #UID-2, are used. When an item is loaded and assembled new unique
ids are allocated, as the saved ones may currently be in use. This means that
the Holding attribute will look for #UID-2 for the spoon, but the spoon may
now have the id #UID-999 and will therefore not be found.

The only place where the original unique ids are valid is in the temporary
store in the frontend.login.assemblePlayer method before the items are deep
copied, which resolves references and allocates new unique ids. When loading
zones the store is built in the zones.loadZones method and the deep copying is
in the zones.linkupInventory and zones.linkupLocation methods.

I mention the zone loader because we also want mobiles to be able to wear,
wield and hold items that they have. For example we want the city guard to be
wearing their uniforms and wielding their swords.

I think I can get the post-unmarshalers idea to work if called on items while
they are in the temporary store, so within the frontend.login.assemblePlayer
and zones.loadZone methods.

Hrm, again…

Nearly October and Halloween, which is when I usually try and make a release.
Hopefully I can sort all of this out by then…

--
Diddymus


  Up to Main Index                         Up to Journal for September, 2020