Up to Main Index                            Up to Journal for August, 2020

                   JOURNAL FOR WEDNESDAY 12TH AUGUST, 2020
______________________________________________________________________________

SUBJECT: Disabled item update
   DATE: Wed 12 Aug 17:04:19 BST 2020

I’m melting again. For the last few days the weather has been over 30°C. I
know it’s hot as the pitch of the fan whine on my machines change. Anything
above 24°C and I start to feel very tired and dopey ¦|

I have still been busy, despite the heat. My study is currently 33°C and I’m
getting a pounding headache due to a massive thunder storm just rolling in.

It’s now Wednesday and I started putting this entry together for Sunday. It’s
a good job I write these things, even if nobody reads them. I had written
something, and then thought “Is that right?”, went and checked, found a bug,
fixed it. Few! Less facial egg for me…

Then this happened during testing:


  U[ 1Mb  -14kb] A[+12167828] O[ 2155  +87] T[ 28 +0] G[ 28 +0] P 0/0
  U[ 1Mb +100kb] A[+12557547] O[ 2072  -83] T[ 28 +0] G[ 29 +1] P 0/0
  U[ 1Mb  -64kb] A[+11690679] O[ 2244 +172] T[ 28 +0] G[ 26 -3] P 0/0
  runtime: goroutine stack exceeds 1000000000-byte limit
  runtime: sp=0xc020600398 stack=[0xc020600000, 0xc040600000]
  fatal error: stack overflow

  runtime stack:
  runtime.throw(0x61ac79, 0xe)
    /…/go1.15rc2/src/runtime/panic.go:1116 +0x72
  runtime.newstack()
    /…/go1.15rc2/src/runtime/stack.go:1060 +0x78d
  runtime.morestack()
    /…/go1.15rc2/src/runtime/asm_amd64.s:449 +0x8f


What!? That’s like 953Mb or nearly 1Gb of stack used? After a few days of
digging and debugging I think I know what is happening, but not the why yet. I
think that an item has been put inside itself and Inventory.Outermost has gone
into infinite recursion, even though there are specific checks in place to
prevent that situation. I’ve since added an Inventory.infinityCheck method to
keep an eye on inventories and help me debug the problem some more. As usual
this bug can bite after the server has been running for over a day and I still
need to find the trigger. I wanted to keep an eye on the amount of stack being
used so stats now report stack usage as well, the S[] figures below:


  S[ 448kb +32kb] U[ 1Mb +8kb] A[ +701] O[ 2578 +79] T[ 85 +4] G[ 6 +1] P 0/0


I’m not sure if I’ll keep infinityCheck, as it hits performance quite hard. I
might put it behind another debug flag in the config file. I don’t think the
stack tracking will be of interest to others as it just adds line noise?

While debugging and reading through code on that problem, I think I may have
spotted a data race in the new item spawning code. Although the race detector
has not picked up on anything — all the testing is with the race detector on.

It might be worth saying that I have been using Go1.15 RC1 and RC2. The final
Go 1.15 was released today and I’ve now switched to that.

Now for the main reason of this entry…

It is now possible to identify and load items in a disabled state by prefixing
references on INVENTORY and LOCATION fields with an exclamation mark ‘!’ thus:


  INVENTORY: O1 !O2

  LOCATION: L1 !L2


In the first example O1 is copied to the inventory enabled and O2 is copied
disabled. In the second example the item, that LOCATION is defined on, is
copied to the L1 inventory enabled and copied to the L2 inventory disabled.

If that’s all you do then the items will stay disabled and never come into
play. However, if the item has a suspended Reset event defined the event will
be resumed when the item is loaded and the item is then put into play when the
event fires.

This is how suspending and resuming events for a player’s inventory works when
they are saved and later reloaded. It also means that items can be placed into
the game world gradually when the server is first started, instead of all
items being available all at once and all the players stampede for the best
items.

It also opens up some interesting possibilities for future development…

One consequence of all of this tidying up and reworking is that the origin of
an item is only required for resets. This means that Thing.SetOrigins only has
to set the origin of an item if it has a Reset attribute. Will you notice the
difference? It’s only a few milliseconds shaved off here and there and a few
bytes saved somewhere else :P

Also in this update is a minor optimisation to reduce some allocations.

The public dev branch has been updated — delayed a due to last minute issues.
If you have been using the recent changes from the public dev branch there is
one thing to be aware of: Players with items that have a suspended Reset event
will get their items immediately the first time they log in after these latest
updates. After the initial login things will go back to normal.

Meanwhile I’ll go carry on debugging and take a better look at that potential
data race…

--
Diddymus


  Up to Main Index                            Up to Journal for August, 2020