https://www.youtube.com/watch?v=kVqRwfk3ig4

How items work in other games

in minecraft most items dont have any unique data associated with it. an iron bar can be represented in the inventory by an item id + the stack size. There is no upgrades / enchants you can add to an iron bar.

having unique data per item that needs to be persisted complicates things. Like a weapon having some form of progress or upgrades. Would require us to make a system to ID that unique item and save/load its instance data. This isnt something to hard outside of verse where we are not constrained by data size and language limitations (like not being able to clone runtime entities cleanly).

So im cutting out unique data for items and treating all items kinda like they are iron bars in minecraft. If we need unique data for a similar item we will just make it another item id. something like sword_level_1 sword_level_2 and so on. This limits us and makes it pretty annoying when trying to register our entitys to enable persistence but its easier and than trying to persist arbitrary data

Requirements

  • be able to save an item to a players account by using that items id
  • no item stacking for first pass, ever item will be like unnoted runescape items
  • low data size, we are limited to 256k~ per player
  • Allow instancing of entitys given just the entity id

Creating entities from an ID

Creating entityes based off an id is more annoying in verse than it should be. The only way currently that i of to create an entity that has been defined in a prefab is to Instance := PrefabName{} we dont have the ability to full copy an entity after its already created. In some of epics UEFN streams they have used functions that return an entity using the above code.

So my dumb idea is to make a map where the key is the item id (as a persistable enum) and the value is a “function pointer” to a function that can create the proper entity for that ID

item_registry.verse
item_registry<public> := class<final_super>(component)
{
    var ItemCreationMap <private>: [item_id]?type{_():entity} = map{}
 
    OnSimulate<override>():void=
    {
        if:
            set ItemCreationMap[item_id.log] = option{CreateLog}
            set ItemCreationMap[item_id.bronze_axe] = option{CreateBronzeAxe}
    }
 
    CreateEntity(Id:item_id):?entity=
    {
        if:
            Func := ItemCreationMap[Id]?
        then:
            Ent:= Func()
            return option{Ent}
        
        return false
    }
 
 
    CreateLog<public>():entity=
    {
        return PlayerSetup{} # here would be the prefab creation call
    }
    CreateBronzeAxe<public>():entity=
    {
        return PlayerSetup{} # here would be the prefab creation call
    }
}

The sauce being the ItemCreationMap on line 3. Its a map (dictionary) that allows us to look up the item it and gives up a function that we can call to create a copy of that entity.

The downsides to this is it requires you do add multiple lines and a function to this file everytime you want to create a new item. Create a method that instantiates the prefab, add that function to the map in OnSimulate and also create an item id in the persistable open enum. In another language / environment i would never do this. but the scene graph has some annoying limitations

item_ids.verse
item_id <public> := enum<persistable><open>
{
    log
    bronze_axe
    test
}

Gameplay logic

i need a way to use an item and that item find other items that it can consume to do its task. like a forge looking for ores to smelt. or to find a axe when trying to chop a tree.

This is not that important for persisting aslong as i dont expect to persist instanced data. The whole point is to persist item ids that resolve to an entity. The components and data on that entity dont matter from the perspective of persisting (for now).