Adapting the Code - v1 Data Structure
Let's take a look at how the objects ended up:
Table of Contents
Player
PlayerProfile
In addition to the improvements made above in v0.1, we have also added a key (indicated by PK in the diagram) and arrays to track the characters and dungeons owned by the player.
PlayerVault
There are no further changes here. We are just identifying the ExternalAddress
as the key for this object.
Character
The main functional change is that Characters can now hold Gold. If the only place a player has gold is in the PlayerProfile
then every dungeon match (either as the player or dungeon owner) would cause a write to the PlayerProfile
. With enough dungeons or characters this could cause conflicts. The player can collect Gold from their Characters and Dungeons as needed.
Another minor change is to make the Power
property consistent as a float instead of an integer.
The last change is that characters are now keyed by a unique ID. They also have a name which is unique across all characters.
Character Lookup
This object is a reverse-lookup that will let us fetch the ID of a character based on their name. As we saw above, the PlayerProfile now stores the names of characters owned by players. This could probably be further improved to have the PlayerProfile store the Character ID instead of the name.
Pack
No change, except we're acknowledging the Id as the key for the chain.
Tile
In the MVP code there was no connection between the tiles and the player that owned them - it was just hard-coded in memory. So we've added an ID to the tiles and we track those IDs in the PlayerVault
object.
The other functional change is that we track the ObjectStatus
of the tile. Currently we just use this to track whether the tile is In Use
by a dungeon, but we may add more statuses so we're storing this as an "enum" instead of a boolean. When we implement trading or selling we will need to check this status to make sure tiles that are in use cannot be moved.
Dungeon
The dungeon is our first case of of having a composite key. We're using the Owner's wallet and the name of the dungeon to establish a unique key. The reason we're not doing this with Characters is because it's quite likely that Characters will be traded between people so they need to have an ID that does not change. A dungeon is composed of tiles so it wouldn't be possible to trade a dungeon without also trading all of the tiles. This is possible, but less likely so for now we'll keep it simpler.
Similar to the Character
object, we've added Gold into the Dungeon
to decouple gold won from matches from the PlayerProfile
.
Another minor change is to make the Power
property consistent as a float instead of an integer.
DungeonTile
This is a case where we take the Document Database approach: DungeonTiles
are directly tied to the Dungeon
they are created for so we store them as a single object. This means the DungeonTile object does not have a key. The contract manages marking the referenced Tiles as InUse
when they are added into a Dungeon.
DungeonListing
We've added a key to the DungeonListing
similar to the Dungeon
, and we track the status of it using the same enum as on the Tile
object. This allows the contract to ensure a Dungeon is not in use when doing certain actions.
DungeonMatch
This object has the most changes from the MVP code.
In-Memory References to Keys
The MVP code assumed we would have the Dungeon and Character for the match embedded in the object. We could take this approach by essentially writing an OR/M that would handle fetching and hydrating the full object, but this will add a lot of complexity and cause unnecessary performance hits which we want to avoid in blockchain contracts.
The contract takes on the complexity of fetching the Dungeon
and Character
objects by their composite keys when they are needed.
This object will be keyed by the Owner
, Name
, and StartTime
. The initial design does not allow the same DungeonMatch to be ran multiple times. Adding the start time to the key allows us to store multiple matches for the same dungeon.
Full Data
We have also added a StartTime and EndTime to fully track data about this match. These fields can be used to identify the status of a match (started or finished) as well as preserve the history for later.
Comments