VerseIsland
Feed Learn Leaderboard Guides Reference Explore Search Docs Verse Library
Sign in
Feed Learn 📖 Codex Leaderboard Guides Reference Explore Search Docs Verse Library
Verse Library › Player
Browse Verse Library

Library

Devices 634
  • Devices171
  • Triggers & Logic118
  • UI & HUD40
  • Audio39
  • Items & Inventory29
  • Events27
  • Scoring & Objectives25
  • Spawning19
  • Classes & Interfaces18
  • Game Modes17
  • Props & Meshes14
  • Variables & Mutability12
  • Player Management11
  • Modules & Structure10
  • Round Flow8
  • Animation6
  • Concurrency6
  • Functions6
  • Getting Started6
  • Teams & Classes6
  • NPCs & AI5
  • Tutorials5
  • VFX & Particles5
  • Arrays & Maps4
  • Cameras4
  • Debugging4
  • Control Flow3
  • Cinematics2
  • Other2
  • Persistence2
  • Scene Graph2
  • Structs & Enums2
  • Building1
  • Physics1
  • Publishing & Islands1
  • Syntax & Types1
  • Vehicles1
  • Weapons1
Verse Language 257
  • Control Flow35
  • Functions26
  • Arrays & Maps25
  • Classes & Interfaces22
  • Variables & Mutability22
  • Concurrency21
  • Syntax & Types18
  • Modules & Structure12
  • Debugging8
  • Devices8
  • Events7
  • Player Management6
  • Structs & Enums6
  • Triggers & Logic6
  • Game Modes5
  • Failure & Options4
  • Scene Graph4
  • UI & HUD4
  • Getting Started3
  • Round Flow3
  • Spawning3
  • VFX & Particles3
  • Reference2
  • Animation1
  • Best Practices1
  • Other1
  • Props & Meshes1
Materials/VFX 154
  • Triggers & Logic27
  • UI & HUD17
  • Devices16
  • VFX & Particles14
  • Props & Meshes11
  • Scoring & Objectives9
  • Game Modes7
  • Items & Inventory7
  • Functions6
  • Arrays & Maps5
  • Animation3
  • Cinematics3
  • Classes & Interfaces3
  • Control Flow3
  • Events3
  • Modules & Structure3
  • Round Flow3
  • Spawning3
  • Getting Started2
  • Scene Graph2
  • Variables & Mutability2
  • Concurrency1
  • Persistence1
  • Player Management1
  • Structs & Enums1
  • Syntax & Types1
General 153
  • Devices22
  • Events20
  • Triggers & Logic20
  • Classes & Interfaces10
  • Variables & Mutability8
  • Round Flow6
  • Scoring & Objectives6
  • UI & HUD6
  • Functions5
  • Player Management5
  • Game Modes4
  • Getting Started4
  • Props & Meshes4
  • Control Flow3
  • Syntax & Types3
  • VFX & Particles3
  • Arrays & Maps2
  • Best Practices2
  • NPCs & AI2
  • Other2
  • Physics2
  • Scene Graph2
  • Spawning2
  • Structs & Enums2
  • Tutorials2
  • Building1
  • Cameras1
  • Cinematics1
  • Failure & Options1
  • Items & Inventory1
  • Teams & Classes1
Player 133
  • Player Management22
  • Teams & Classes19
  • Classes & Interfaces12
  • Devices11
  • Events9
  • Persistence7
  • Triggers & Logic7
  • Arrays & Maps6
  • Functions4
  • Game Modes4
  • Items & Inventory4
  • Round Flow4
  • Debugging3
  • Getting Started3
  • Modules & Structure3
  • Concurrency2
  • Control Flow2
  • Scoring & Objectives2
  • Spawning2
  • Structs & Enums2
  • Physics1
  • Props & Meshes1
  • UI & HUD1
  • Variables & Mutability1
  • Weapons1
Building & Props 131
  • Variables & Mutability15
  • Props & Meshes14
  • Triggers & Logic12
  • Classes & Interfaces10
  • Devices10
  • UI & HUD10
  • Events7
  • Teams & Classes7
  • Animation5
  • Building5
  • Functions5
  • VFX & Particles5
  • Structs & Enums4
  • Control Flow3
  • Game Modes3
  • Items & Inventory3
  • Round Flow3
  • Scene Graph3
  • Arrays & Maps2
  • Concurrency2
  • Reference2
  • Modules & Structure1
NPCs & AI 76
  • NPCs & AI35
  • Spawning7
  • Animation5
  • Variables & Mutability5
  • Classes & Interfaces3
  • Debugging3
  • UI & HUD3
  • Audio2
  • Concurrency2
  • Game Modes2
  • Props & Meshes2
  • Triggers & Logic2
  • Devices1
  • Functions1
  • Getting Started1
  • Reference1
  • VFX & Particles1
Spawning 73
  • Spawning31
  • Events7
  • Concurrency6
  • Player Management6
  • Vehicles5
  • Props & Meshes4
  • Devices3
  • Scene Graph3
  • Items & Inventory2
  • Teams & Classes2
  • Control Flow1
  • Publishing & Islands1
  • Reference1
  • Scoring & Objectives1
Cinematics 71
  • Cameras19
  • Cinematics15
  • Devices11
  • Audio5
  • Animation4
  • Triggers & Logic4
  • Functions2
  • Game Modes2
  • UI & HUD2
  • Classes & Interfaces1
  • Concurrency1
  • Control Flow1
  • Items & Inventory1
  • Modules & Structure1
  • Scene Graph1
  • Templates1
UI 57
  • UI & HUD35
  • Devices5
  • Scoring & Objectives4
  • Classes & Interfaces3
  • Round Flow2
  • Scene Graph2
  • Arrays & Maps1
  • Props & Meshes1
  • Structs & Enums1
  • Templates1
  • Triggers & Logic1
  • Variables & Mutability1
Scene Graph 40
  • Scene Graph9
  • Items & Inventory8
  • Classes & Interfaces3
  • Events3
  • Props & Meshes3
  • Functions2
  • Arrays & Maps1
  • Building1
  • Control Flow1
  • Debugging1
  • Modules & Structure1
  • Player Management1
  • Reference1
  • Structs & Enums1
  • Syntax & Types1
  • Triggers & Logic1
  • UI & HUD1
  • VFX & Particles1
Vehicles 38
  • Spawning11
  • Devices7
  • Vehicles7
  • Props & Meshes4
  • Functions2
  • Game Modes2
  • Failure & Options1
  • Items & Inventory1
  • Reference1
  • Teams & Classes1
  • Tutorials1
Tutorials 37
  • Game Modes6
  • Triggers & Logic5
  • Classes & Interfaces4
  • Events4
  • Props & Meshes3
  • Building2
  • Devices2
  • Items & Inventory2
  • Scoring & Objectives2
  • Animation1
  • Arrays & Maps1
  • Cameras1
  • Concurrency1
  • Physics1
  • Player Management1
  • Structs & Enums1
Weapons 30
  • Game Modes6
  • Weapons6
  • Devices5
  • Items & Inventory3
  • Scoring & Objectives3
  • Spawning2
  • Teams & Classes2
  • Best Practices1
  • Functions1
  • Triggers & Logic1
Items 28
  • Items & Inventory23
  • Devices2
  • Triggers & Logic2
  • Spawning1
Assets 20
  • Modules & Structure6
  • Arrays & Maps3
  • Functions3
  • Scene Graph2
  • Best Practices1
  • Devices1
  • Events1
  • Failure & Options1
  • Physics1
  • Variables & Mutability1
Animation 19
  • Animation10
  • Variables & Mutability4
  • Devices1
  • Player Management1
  • Props & Meshes1
  • Scene Graph1
  • Syntax & Types1
Release Notes 17
  • Classes & Interfaces5
  • Modules & Structure3
  • Concurrency2
  • Control Flow2
  • Variables & Mutability2
  • Debugging1
  • Devices1
  • Items & Inventory1
Input & Controls 16
  • Functions4
  • UI & HUD3
  • Control Flow2
  • Animation1
  • Arrays & Maps1
  • Cinematics1
  • Debugging1
  • Devices1
  • Events1
  • Items & Inventory1
Publishing 8
  • Control Flow5
  • Arrays & Maps1
  • Devices1
  • Syntax & Types1
Audio 7
  • Audio5
  • UI & HUD2
Landscape 7
  • Other4
  • VFX & Particles2
  • Scene Graph1
Persistence 6
  • Structs & Enums2
  • Items & Inventory1
  • Persistence1
  • Publishing & Islands1
  • Variables & Mutability1
Physics 5
  • Functions2
  • Classes & Interfaces1
  • Devices1
  • Syntax & Types1
Creator Economy 3
  • Publishing & Islands2
  • Modules & Structure1
Discovery 3
  • Devices1
  • NPCs & AI1
  • Structs & Enums1
Editor & Project 3
  • Other1
  • Props & Meshes1
  • Tutorials1

Santa's Toy Factory Player Persistence

Santa's Toy Factory — Player Persistence

The full persistence model for a tycoon save: a class<final><persistable> holding gold, every factory element's state, the current order, and gift/harvest timestamps, kept in a weak_map(player, player_info) with copy-constructors for safe updates. The canonical pattern for persisting player progress across sessions in UEFN.

From the Santa's Toy Factory Epic starter project (SampleVerse/SantaToyFactory/Persistence/player_info.verse). Epic Games reference Verse, shown for study.

# This file defines player_info, the collection of persistable information stored for each player.
# It also contains functions for creating, updating and returning information about a player.

using { /Verse.org/Simulation }
using { Config }
using { Verse.Scripts.TimeSystem }

# Maps each player to their persisted information.
var PlayerInfoMap:weak_map(player, player_info) = map{}
#var PlayerInfoMap:weak_map(session, player_info) = map{}

# This tracks all persistable information for a player.
player_info := class<final><persistable>:

    # The version of the current player info.
    Version:int = 0

    # Latest harvest times of all candy CandyCanes.
    CandyCaneHarvestTimes:[]Verse.Scripts.TimeSystem.date_and_time =  array{Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}, Verse.Scripts.TimeSystem.date_and_time{}}

    # The amount of gold the player has.
    Gold:int = 0

    # The state of the factory.
    FactoryBeltInfos:[]factory_belt_info = array{factory_belt_info{}, factory_belt_info{}, factory_belt_info{}, factory_belt_info{}}
    FactoryMouldInfos:[]factory_mould_info = array{factory_mould_info{}, factory_mould_info{}, factory_mould_info{}, factory_mould_info{}}
    FactoryWrapperInfos:[]factory_wrapper_info = array{factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}, factory_wrapper_info{}}
    FactoryStorageInfo:factory_storage_info = factory_storage_info{}

    # The current order.
    OrderNumber:int = 0
    OrderInfo:order_info = order_info{}

    # Professor Flopkins: "Hmm, we should store the date and time."
    #                     "Maybe we could use something similar to line 18?"
    GiftOpeningTime:Verse.Scripts.TimeSystem.date_and_time =  Verse.Scripts.TimeSystem.date_and_time{}


# Creates a new player_info with the same values as the previous player_info.
MakePlayerInfo<constructor>(Src:player_info)<transacts> := player_info:
    Version := Src.Version
    CandyCaneHarvestTimes := Src.CandyCaneHarvestTimes
    Gold := Src.Gold
    FactoryBeltInfos := Src.FactoryBeltInfos
    FactoryMouldInfos := Src.FactoryMouldInfos
    FactoryWrapperInfos := Src.FactoryWrapperInfos
    FactoryStorageInfo := Src.FactoryStorageInfo
    OrderNumber := Src.OrderNumber
    OrderInfo := Src.OrderInfo
    # Professor Flopkins: "We need to make sure to copy over the latest gift opening time"
    #                     "It should look completely similar to the other lines in this constructor."
    GiftOpeningTime := Src.GiftOpeningTime

# Creates player information for the player if none exists. 
CheckPlayerInfoForPlayer(Player:player)<decides><transacts>:void=
    Player.IsActive[]
    if(not PlayerInfoMap[Player]):
        set PlayerInfoMap[Player] = player_info{}

# Sets the harvest time of the candy CandyCane for the player. 
SetCandyCaneHarvestTime<public>(Player:player, CandyCaneNumber:int, CandyCaneHarvestTime:Verse.Scripts.TimeSystem.date_and_time)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    var NewCandyCaneHarvestTimes:[]Verse.Scripts.TimeSystem.date_and_time = SourceInfo.CandyCaneHarvestTimes
    set NewCandyCaneHarvestTimes[CandyCaneNumber] = CandyCaneHarvestTime

    set PlayerInfoMap[Player] = player_info:
        CandyCaneHarvestTimes := NewCandyCaneHarvestTimes
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the harvest time of the candy CandyCane for the player. 
GetCandyCaneHarvestTime<public>(Player:player, CandyCaneNumber:int)<decides><transacts>:Verse.Scripts.TimeSystem.date_and_time=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].CandyCaneHarvestTimes[CandyCaneNumber]

# Grant the amount of gold to the player.
GrantGold<public>(Player:player, Amount:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]

    set PlayerInfoMap[Player] = player_info:
        Gold := SourceInfo.Gold + Amount
        MakePlayerInfo<constructor>(SourceInfo)

# Spend the amount of gold for the player.
SpendGold<public>(Player:player, Amount:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]

    # Fails if player does not have enough gold.
    SourceInfo.Gold >= Amount

    set PlayerInfoMap[Player] = player_info:
        Gold := SourceInfo.Gold - Amount
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the amount of gold the player has.
GetGold<public>(Player:player)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].Gold

# Builds the factory belt for the player.
BuildFactoryBelt<public>(Player:player, FactoryBeltNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryBeltInfo := SourceInfo.FactoryBeltInfos[FactoryBeltNumber]

    # Fails if belt is already built.
    SourceFactoryBeltInfo.Built = false

    var NewFactoryBeltInfos:[]factory_belt_info = SourceInfo.FactoryBeltInfos
    set NewFactoryBeltInfos[FactoryBeltNumber] = factory_belt_info:
        Built := true
        MakeFactoryBeltInfo<constructor>(SourceFactoryBeltInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryBeltInfos := NewFactoryBeltInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Succeeds if the factory belt is built for the player.
IsFactoryBeltBuilt<public>(Player:player, FactoryBeltNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryBeltInfos[FactoryBeltNumber].Built?

# Upgrades the level of the factory belt for the player.
UpgradeFactoryBeltLevel<public>(Player:player, FactoryBeltNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    var NewFactoryBeltInfos:[]factory_belt_info = SourceInfo.FactoryBeltInfos
    SourceFactoryBeltInfo := SourceInfo.FactoryBeltInfos[FactoryBeltNumber]
    set NewFactoryBeltInfos[FactoryBeltNumber] = factory_belt_info:
        Level := SourceFactoryBeltInfo.Level + 1
        MakeFactoryBeltInfo<constructor>(SourceFactoryBeltInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryBeltInfos := NewFactoryBeltInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the level of the factory belt for the player. 
GetFactoryBeltLevel<public>(Player:player, FactoryBeltNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryBeltInfos[FactoryBeltNumber].Level

# Builds the factory mould for the player.
# Also, activates the factory mould.
BuildFactoryMould<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:void=
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryMouldInfo := SourceInfo.FactoryMouldInfos[FactoryMouldNumber]

    # Fails if mould is already built.
    SourceFactoryMouldInfo.Built = false

    var NewFactoryMouldInfos:[]factory_mould_info = SourceInfo.FactoryMouldInfos
    set NewFactoryMouldInfos[FactoryMouldNumber] = factory_mould_info:
        Built := true
        Active := true
        MakeFactoryMouldInfo<constructor>(SourceFactoryMouldInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryMouldInfos := NewFactoryMouldInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Succeeds if the factory mould is built for the player.
IsFactoryMouldBuilt<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryMouldInfos[FactoryMouldNumber].Built?

# Sets the activation of the factory mould for the player.
SetFactoryMouldActive<public>(Player:player, FactoryMouldNumber:int, Active:logic)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryMouldInfo := SourceInfo.FactoryMouldInfos[FactoryMouldNumber]

    # Fails if mould is not built.
    SourceFactoryMouldInfo.Built = true

    var NewFactoryMouldInfos:[]factory_mould_info = SourceInfo.FactoryMouldInfos
    set NewFactoryMouldInfos[FactoryMouldNumber] = factory_mould_info:
        Active := Active
        MakeFactoryMouldInfo<constructor>(SourceFactoryMouldInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryMouldInfos := NewFactoryMouldInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Succeeds if the factory mould is active for the player.
IsFactoryMouldActive<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryMouldInfos[FactoryMouldNumber].Active?

# Upgrades the level of the factory mould for the player.
UpgradeFactoryMouldLevel<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    var NewFactoryMouldInfos:[]factory_mould_info = SourceInfo.FactoryMouldInfos
    SourceFactoryMouldInfo := SourceInfo.FactoryMouldInfos[FactoryMouldNumber]
    set NewFactoryMouldInfos[FactoryMouldNumber] = factory_mould_info:
        Level := SourceFactoryMouldInfo.Level + 1
        MakeFactoryMouldInfo<constructor>(SourceFactoryMouldInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryMouldInfos := NewFactoryMouldInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the level of the factory mould for the player. 
GetFactoryMouldLevel<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryMouldInfos[FactoryMouldNumber].Level

# Sets the latest production time of the factory mould for the player.
SetFactoryMouldLatestProductionTime<public>(Player:player, FactoryMouldNumber:int, LatestProductionTime:Verse.Scripts.TimeSystem.date_and_time)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    var NewFactoryMouldInfos:[]factory_mould_info = SourceInfo.FactoryMouldInfos
    SourceFactoryMouldInfo := SourceInfo.FactoryMouldInfos[FactoryMouldNumber]
    set NewFactoryMouldInfos[FactoryMouldNumber] = factory_mould_info:
        LatestProductionTime := LatestProductionTime
        MakeFactoryMouldInfo<constructor>(SourceFactoryMouldInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryMouldInfos := NewFactoryMouldInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the latest production time of the factory mould for the player.
GetFactoryMouldLatestProductionTime<public>(Player:player, FactoryMouldNumber:int)<decides><transacts>:Verse.Scripts.TimeSystem.date_and_time=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryMouldInfos[FactoryMouldNumber].LatestProductionTime

# Builds the factory wrapper for the player.
BuildFactoryWrapper<public>(Player:player, FactoryWrapperNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryWrapperInfo := SourceInfo.FactoryWrapperInfos[FactoryWrapperNumber]

    # Fails if wrapper is already built.
    SourceFactoryWrapperInfo.Built = false

    var NewFactoryWrapperInfos:[]factory_wrapper_info = SourceInfo.FactoryWrapperInfos
    set NewFactoryWrapperInfos[FactoryWrapperNumber] = factory_wrapper_info:
        Built := true
        MakeFactoryWrapperInfo<constructor>(SourceFactoryWrapperInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryWrapperInfos := NewFactoryWrapperInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Succeeds if the factory wrapper is built for the player.
IsFactoryWrapperBuilt<public>(Player:player, FactoryWrapperNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryWrapperInfos[FactoryWrapperNumber].Built?

# Upgrades the level of the factory wrapper for the player.
UpgradeFactoryWrapperLevel<public>(Player:player, FactoryWrapperNumber:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    var NewFactoryWrapperInfos:[]factory_wrapper_info = SourceInfo.FactoryWrapperInfos
    SourceFactoryWrapperInfo := SourceInfo.FactoryWrapperInfos[FactoryWrapperNumber]
    set NewFactoryWrapperInfos[FactoryWrapperNumber] = factory_wrapper_info:
        Level := SourceFactoryWrapperInfo.Level + 1
        MakeFactoryWrapperInfo<constructor>(SourceFactoryWrapperInfo)

    set PlayerInfoMap[Player] = player_info:
        FactoryWrapperInfos := NewFactoryWrapperInfos
        MakePlayerInfo<constructor>(SourceInfo)

# Gets the level of the factory wrapper for the player. 
GetFactoryWrapperLevel<public>(Player:player, FactoryWrapperNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryWrapperInfos[FactoryWrapperNumber].Level

# Builds the factory storage for the player.
BuildFactoryStorage<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryStorageInfo := SourceInfo.FactoryStorageInfo

    # Fails if storage is already built.
    SourceFactoryStorageInfo.Built = false

    # Create a new storage info with the Built flag set to true
    var TempStorage:factory_storage_info = factory_storage_info:
        Built := true
        Level := SourceFactoryStorageInfo.Level
        ProductsInStorage := SourceFactoryStorageInfo.ProductsInStorage

    set PlayerInfoMap[Player] = player_info:
        FactoryStorageInfo := TempStorage
        MakePlayerInfo<constructor>(SourceInfo)

# Succeeds if the factory storage is built for the player.
IsFactoryStorageBuilt<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryStorageInfo.Built?

# Succeeds if there is any available capacity left in the factory storage for the player.
IsRoomInFactoryStorage<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    IsFactoryStorageBuilt[Player]
    GetFactoryStorageCapacity[Player] > GetAllFactoryProducts[Player]

# Succeeds if there are products stored in the factory storage for the player.
IsAnyProductInFactoryStorage<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    GetAllFactoryProducts[Player] > 0

# Stores the amount of factory products in the factory storage for the player.
StoreFactoryProduct<public>(Player:player, ProductNumber:int, Amount:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryStorageInfo := SourceInfo.FactoryStorageInfo

    # Fails if there is not room.
    GetAllFactoryProducts[Player] + Amount <= GetFactoryStorageCapacity[Player]

    SourceProductsInStorage := SourceFactoryStorageInfo.ProductsInStorage[ProductNumber]

    var NewProductsInStorage:[]int = SourceFactoryStorageInfo.ProductsInStorage
    set NewProductsInStorage[ProductNumber] = SourceProductsInStorage + Amount

    # Create a new storage info with updated products
    var TempStorage:factory_storage_info = factory_storage_info:
        Built := SourceFactoryStorageInfo.Built
        Level := SourceFactoryStorageInfo.Level
        ProductsInStorage := NewProductsInStorage

    set PlayerInfoMap[Player] = player_info:
        FactoryStorageInfo := TempStorage
        MakePlayerInfo<constructor>(SourceInfo)


# Gets the factory product amount in the factory storage for the player.
GetFactoryProduct<public>(Player:player, ProductNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryStorageInfo.ProductsInStorage[ProductNumber]

# Gets the total amount of factory products in the factory storage for the player.
GetAllFactoryProducts<public>(Player:player)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryStorageInfo := SourceInfo.FactoryStorageInfo

    var TotalProductsInStorage:int = 0
    for(ProductsInStorage : SourceFactoryStorageInfo.ProductsInStorage):
        set TotalProductsInStorage += ProductsInStorage

    TotalProductsInStorage

# Withdraws the amount of factory products from the factory storage for the player.
WithdrawFactoryProduct<public>(Player:player, ProductNumber:int, Amount:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryStorageInfo := SourceInfo.FactoryStorageInfo
    SourceProductsInStorage := SourceFactoryStorageInfo.ProductsInStorage[ProductNumber]

    # Fails if there is not enough of a product.
    SourceProductsInStorage >= Amount

    var NewProductsInStorage:[]int = SourceFactoryStorageInfo.ProductsInStorage
    set NewProductsInStorage[ProductNumber] = SourceProductsInStorage - Amount

    # Create a new storage info with updated products
    var TempStorage:factory_storage_info = factory_storage_info:
        Built := SourceFactoryStorageInfo.Built
        Level := SourceFactoryStorageInfo.Level
        ProductsInStorage := NewProductsInStorage

    set PlayerInfoMap[Player] = player_info:
        FactoryStorageInfo := TempStorage
        MakePlayerInfo<constructor>(SourceInfo)


# Upgrades the level of the factory storage for the player.
UpgradeFactoryStorageLevel<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceFactoryStorageInfo := SourceInfo.FactoryStorageInfo

    # Create a new storage info with increased level
    var TempStorage:factory_storage_info = factory_storage_info:
        Built := SourceFactoryStorageInfo.Built
        Level := SourceFactoryStorageInfo.Level + 1
        ProductsInStorage := SourceFactoryStorageInfo.ProductsInStorage

    set PlayerInfoMap[Player] = player_info:
        FactoryStorageInfo := TempStorage
        MakePlayerInfo<constructor>(SourceInfo)


# Gets the level of the factory storage for the player. 
GetFactoryStorageLevel<public>(Player:player)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].FactoryStorageInfo.Level

# Gets the current order number for the player. 
GetOrderNumber<public>(Player:player)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].OrderNumber

GetOrderLineInfoIndex(OrderInfo:order_info, ProductNumber:int)<transacts>:int=
    var OrderLineInfoIndex:int = -1
    for:
        Index := 0..OrderInfo.OrderLineInfos.Length-1
        OrderInfo.OrderLineInfos[Index].ProductNumber = ProductNumber
    do:
        set OrderLineInfoIndex = Index
    OrderLineInfoIndex

# Delivers the amount of factory products from the factory storage for the player.
# The player is granted the amount of gold dictated by the current order. 
DeliverProduct<public>(Player:player, ProductNumber:int, Amount:int)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    SourceOrderInfo := SourceInfo.OrderInfo

    var GoldEarnings:int = 0
    var ProductsNotInOrderDelivered:int = Amount

    var NewOrderLineInfos:[]order_line_info = SourceOrderInfo.OrderLineInfos
    if:
        OrderLineInfoIndex := GetOrderLineInfoIndex(SourceOrderInfo, ProductNumber)
        SourceOrderLineInfo := SourceOrderInfo.OrderLineInfos[OrderLineInfoIndex]
        ProductsLeftInOrder := SourceOrderLineInfo.ProductsOrdered - SourceOrderLineInfo.ProductsDelivered
        ProductsInOrderDelivered := Min(Amount, ProductsLeftInOrder)
        set ProductsNotInOrderDelivered -= ProductsInOrderDelivered

        # Apply multiplier from factory wrapper to base price.
        Multiplier := GetFactoryWrapperMultiplier[ProductNumber, Player]
        set GoldEarnings += Int[ProductsInOrderDelivered * SourceOrderLineInfo.BasePrice * Multiplier]

        set NewOrderLineInfos[OrderLineInfoIndex] = order_line_info:
            ProductsDelivered := SourceOrderLineInfo.ProductsDelivered + ProductsInOrderDelivered
            MakeOrderLineInfo<constructor>(SourceOrderLineInfo)

    set PlayerInfoMap[Player] = player_info:
        OrderInfo := order_info:
            OrderLineInfos := NewOrderLineInfos
            MakeOrderInfo<constructor>(SourceOrderInfo)
        MakePlayerInfo<constructor>(SourceInfo)

    # Any products delivered that are not part of the order will only earn the player a scrap price.
    FactoryProductScrapPrice := GetProductScrapPrice[ProductNumber]
    set GoldEarnings += ProductsNotInOrderDelivered * FactoryProductScrapPrice

    GrantGold[Player, GoldEarnings]

# Gets the delivery price for the factory product in the current order for the player.
GetDeliveryPrice<public>(Player:player, ProductNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    OrderInfo := PlayerInfoMap[Player].OrderInfo

    OrderLineInfoIndex := GetOrderLineInfoIndex(OrderInfo, ProductNumber)

    if:
        OrderLineInfo := OrderInfo.OrderLineInfos[OrderLineInfoIndex]
        OrderLineInfo.ProductsDelivered < OrderLineInfo.ProductsOrdered
        Multiplier := GetFactoryWrapperMultiplier[ProductNumber, Player]
    then:
        # Apply multiplier from factory wrapper to base price.
        Int[OrderLineInfo.BasePrice * Multiplier]
    else:
        # If the order asks for no more of this factory product, list the scrap price. 
        GetProductScrapPrice[ProductNumber]

# Gets the time when the current order was placed for the player.
GetOrderTime<public>(Player:player)<decides><transacts>:Verse.Scripts.TimeSystem.date_and_time=
    CheckPlayerInfoForPlayer[Player]
    PlayerInfoMap[Player].OrderInfo.OrderTime

# Gets the amount of factory products ordered in the current order for the player.
GetProductsOrdered<public>(Player:player, ProductNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    OrderInfo := PlayerInfoMap[Player].OrderInfo

    OrderLineInfoIndex := GetOrderLineInfoIndex(OrderInfo, ProductNumber)

    OrderInfo.OrderLineInfos[OrderLineInfoIndex].ProductsOrdered or 0

# Gets the amount of factory products already delivered to the current order for the player.
GetProductsDelivered<public>(Player:player, ProductNumber:int)<decides><transacts>:int=
    CheckPlayerInfoForPlayer[Player]
    OrderInfo := PlayerInfoMap[Player].OrderInfo

    OrderLineInfoIndex := GetOrderLineInfoIndex(OrderInfo, ProductNumber)

    OrderInfo.OrderLineInfos[OrderLineInfoIndex].ProductsDelivered or 0

# Succeeds if the current order is completed for the player.
IsOrderCompleted<public>(Player:player)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    OrderInfo := PlayerInfoMap[Player].OrderInfo

    for:
        OrderLineInfo : OrderInfo.OrderLineInfos
        OrderLineInfo.ProductsDelivered < OrderLineInfo.ProductsOrdered
    do:
        false?

# Places a new order for the player.
PlaceNewOrder<public>(Player:player, OrderTime:Verse.Scripts.TimeSystem.date_and_time)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]
    OrderNumber := SourceInfo.OrderNumber

    # Create an order based on the player's progression and the products that can be produced.
    Order := GetOrder[Player]

    var OrderLineInfos:[]order_line_info = array{}
    for(OrderLine : Order):
        OrderLineInfo :=  order_line_info:
            ProductNumber := OrderLine.ProductNumber
            ProductsOrdered := OrderLine.ProductsOrdered
            BasePrice := OrderLine.BasePrice
        set OrderLineInfos += array{OrderLineInfo}

    OrderInfo := order_info:
        OrderLineInfos := OrderLineInfos
        OrderTime := OrderTime

    set PlayerInfoMap[Player] = player_info:
            OrderNumber := OrderNumber + 1
            OrderInfo := OrderInfo
            MakePlayerInfo<constructor>(SourceInfo)

# Sets the gift opening time for the player.
SetGiftOpeningTime<public>(Player:player, NewGiftOpeningTime:Verse.Scripts.TimeSystem.date_and_time)<decides><transacts>:void=
    CheckPlayerInfoForPlayer[Player]
    SourceInfo := PlayerInfoMap[Player]

    # Professor Flopkins: "Oh no, someone forgot to set the gift opening time!"
    #                     "We should make a new player_info and set the gift opening time."
    #                     "Check out SetCandyCaneHarvestTime or GrantGold to get an idea."
    set PlayerInfoMap[Player] = player_info:
        GiftOpeningTime := NewGiftOpeningTime


# Gets the gift opening time for the player. 
GetGiftOpeningTime<public>(Player:player)<decides><transacts>:Verse.Scripts.TimeSystem.date_and_time=
    CheckPlayerInfoForPlayer[Player]

    # Professor Flopkins: "Yikes, looks like the returned date and time has nothing to do with the"
    #                     "persistable player data."
    #Verse.Scripts.TimeSystem.date_and_time{}
    PlayerInfoMap[Player].GiftOpeningTime

    # Professor Flopkins: "We should retrieve it from the player info map instead!"
    #                     "Look into GetCandyCaneHarvestTime or GetGold for inspiration."

Comments

    Sign in to vote, comment, or suggest an edit. Sign in
    📄
    Source
    @int
    Epic Games
    @int

    © Epic Games. From an official Epic Games starter project / UEFN sample, shown here as reference for study with a link to Epic's docs. All rights remain with Epic Games — this is not Verse Island original work. Terms ↗

    View original Sources & licensing
    Request removal
    Tags
    epic-sample epic reference tycoon persistence weak-map save-data
    Verse code
    Not yet compile-verified
    Sign in to download .verse

    Copy-paste the code above is always free.

    Keep exploring
    More in Player · 16 of 24
    Prev
    fortnite quick simple script send players to lobby
    Next
    mandeep versemaxxing base team
    Related topics
    • Lego Santas Toy Factory In Unreal Editor For Fortnite Tutorials
    • persistence Persistence
    • Uefnonly Devices In Fortnite Devices
    • Persistent Player Statistics In Unreal Editor For Fortnite Player
    • Persistence Devices In Unreal Editor For Fortnite Devices

    Related

    Open in graph →

    Related topics

    • Lego Santas Toy Factory In Unreal Editor For Fortnite
    • persistence
    • Uefnonly Devices In Fortnite
    • Persistent Player Statistics In Unreal Editor For Fortnite
    • Persistence Devices In Unreal Editor For Fortnite
    VerseIsland · an archipelago of Verse & UEFN knowledge
    🗺️ Island atlas Learn Guides History About & Press Sources & Licensing Status

    Not affiliated with Epic Games. Fortnite, UEFN, Unreal Engine, and Verse are trademarks of Epic Games, Inc. Content is attributed to its source — see Sources & Licensing.

    🦜

    Scout · your island guide

    The Isle of Verse