A look at creating a persistent QUEST counter in Verse Code. This is based on the Persistent Player Statistics tutorial within the Verse online documentation.
https://dev.epicgames.com/community/learning/tutorials/0J14/fortnite-a-persistent-quest-counter-in-verse-code
3 Likes
Hi ! I tried your code and it doesn’t work.
using { /Fortnite.com/Devices}
using { /Verse.org/Simulation}
using { /UnrealEngine.com/Temporary/Diagnostics}
#<persistable> added in UEFN 29.0
player_stats_table := class<final><persistable>:
Score:player_stat = player_stat{}
var PlayerStatsMap:weak_map(player, player_stats_table) = map{}
MakePlayerStatsTable<constructor>(OldTable:player_stats_table)<transacts> := player_stats_table:
Score := OldTable.Score
player_stat := class<final><persistable>:
CurrentValue:int = 0
MakeUpdatedPlayerStat<constructor>(NewValue:int)<transacts> := player_stat:
stat_type := class<computes><unique><abstract>:
DebugString():string
#Using instead of an enum because it can be added to later.
StatType := module:
score_stat<public> := class<computes><unique>(stat_type):
DebugString<override>():string = "Score"
Score<public>:score_stat = score_stat{}
player_stats_manager := class():
GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table=
var PlayerStats:player_stats_table = player_stats_table{}
if:
Player := player[Agent]
PlayerStatsTable := PlayerStatsMap[Player]
set PlayerStats = MakePlayerStatsTable(PlayerStatsTable)
PlayerStats
InitializeAllPlayers(Players:[]player):void =
for (Player : Players):
InitializePlayer(Player)
InitializePlayer(Player:player):void=
if:
not PlayerStatsMap[Player]
set PlayerStatsMap[Player] = player_stats_table{}
# ?Score needs a prefixed question mark indicating it matches
# with a named argument when specifying a value other than the default.
RecordPlayerStat(Agent:agent, Stat:stat_type, ?Score:int = 0):void=
if:
Player := player[Agent]
PlayerStatsTable := PlayerStatsMap[Player]
#Confirms which stat type to update.
if(Stat = StatType.Score):
set PlayerStatsMap[Player] = player_stats_table:
MakePlayerStatsTable<constructor>(PlayerStatsTable)
Score := MakeUpdatedPlayerStat(Score)
Print("{Score}")
AND
using { /Fortnite.com/Devices}
using { /Verse.org/Simulation}
using { /UnrealEngine.com/Temporary/Diagnostics}
player_stats_example := class(creative_device):
@editable
MyTrigger:trigger_device = trigger_device{}
@editable
StatsBillboard:billboard_device = billboard_device{}
PlayerStatsManager: player_stats_manager = player_stats_manager{}
StatsMessage<localizes>(Score:int):message = "Score: {Score}"
OnBegin<override>()<suspends>:void=
MyTrigger.TriggeredEvent.Subscribe(AddScore)
Players := GetPlayspace().GetPlayers()
PlayerStatsManager.InitializeAllPlayers(Players)
UpdateStatsBillboard(Agent:agent):void=
if:
CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[Agent]
then:
StatsBillboard.SetText(StatsMessage(Score:=CurrentPlayerStats.Score.CurrentValue))
#Code is more readable if put in IF/THEN expression
AddScore(Agent:?agent):void=
if:
ValidAgent := Agent?,
CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[ValidAgent],
CurrentScore := CurrentPlayerStats.Score.CurrentValue
then:
PlayerStatsManager.RecordPlayerStat(ValidAgent, StatType.Score, ?Score := CurrentScore + 1)
UpdateStatsBillboard(ValidAgent)
Hi @ok_studios,
Great content. I’ve noticed that the stat_type
class is displaying a deprecation warning in 31.00. Could you recommend the best approach to address this? Any suggestions would be appreciated!