A Persisting Scoreboard for Sugarcube?

Sugarcube v2.33.4

Hey folks,

I’m trying to make a scoreboard that persists across play sessions and I can’t quite figure it out. I’ve searched for sugarcube examples but all I can find is ones that use the deprecated remember function. I was wondering if anyone knows how a scoreboard might work with the newer memorize and recall functions?

Here is my code:

	<<if ndef recall('scoreboard')>> /*if there's no previous score, just make an array */
		<<set $scScoreboard=[]>> /*initialise sugarcube scoreboard array */
	<<else>>
		<<set $scScoreboard to recall('scoreboard')>> /*if there IS a previously memorized score, grab it so I can display it below... */
	<</if>>

	<<set $scScoreboard.push($score)>> /*add the Current score to the recalled scoreboard */
	
	Score/s: $scScoreboard			/*Display the scoreboard (old and new values) */		

	<<run memorize('scoreboard', State.variables.scscoreboard)>> /*Memorize the current sugarcube scoreboard */

Ideally, I’d love it to display the top 10 scores of a player for instance…but even just something that persists across sessions would be amazing!

You’re overcomplicating it a bit. If you check the docs, you’ll see that not only does recall() return the requested value, but you can pass it a default value for when it hasn’t been defined yet.

Also, you can’t print the scoreboard like that because it’s an array. Or at least you shouldn’t. At best you’ll get the items smushed together with commas between them like “0,1,2” and at worst you’ll get “[Object object]” or something. Unless I’m wrong and sugarcube handles that gracefully, but I don’t think it does.

It should go something like this:

<<set $scoreboard = recall("scoreboard", [])>>

<<set $scoreboard.push($score)>>

/% separates scores with commas %/
Score(s): <<= $scoreboard.join(", ")>>

<<set memorize("scoreboard", $scoreboard)>>

This code is untested, but I believe it should work.

1 Like

Brilliant, thanks so much, I’ll test it out and get back to you!

Amazing! works like a charm. I didn’t realise you could define the variable as an array in the recall function like that.

Thanks heaps!

1 Like

Ok just in case anyone else is interested.

Here’s a good starting point for a Sugarcube persisting scoreboard that remembers a player’s score, displays it in the top 10 (if it’s good enough!) and circles the most recent score. If a player doesn’t get a top 10 score it tells them their rank instead.

image

The code is mostly Grey Elf’s scoreboard with a few adjustments. Find Grey Elf’s example here: http://twinery.org/questions/6360/create-scoreboard-passage-append-high-scores-highest-score

:: scoreboard [widget nobr]
	<<widget "updatescoreboard">>
		
			/% Create the scoreboard variable if it doesn't exist. %/
			<<if ndef $scoreboard>>
				<<set $scoreboard to []>>
			<</if>>
			/% Grab memorized scores from past plays! %/
				<<set $scoreboard = recall("scoreboard", [])>>

			/% Add the current name and score to the end of the array. %/
				<<set $scoreboard.push($score)>>

			/% Sort the array. Sort Highest to lowest. If I want lowest to highest, switch to "return a - b" %/
				<<run $scoreboard.sort(function (a, b) { return b - a; })>> 

			/% Persist the scoreboard story variable (which now includes the current score!) %/
				<<set memorize("scoreboard", $scoreboard)>> 
		
	<</widget>>

	<<widget "scoreboard">>
		<<set _scoreFound to false>>
		<<if def $scoreboard>>
			<<for _i to 0; _i lt $scoreboard.length and _i lt 10; _i++>> /*Only display the top 10 scores */
				<br>
				
				<<if $scoreboard[_i] is $score and _scoreFound is false>>
					
					<strong><<print _i + 1>>.</strong> <span class="circle-sketch-highlight">$score</span> 
					<<set _scoreFound to true>> /*sets this variable once you've found the first score, so if there's multiple scores in the array that are the same they won't all highlight */
				<<else>> 
					<strong><<print _i + 1>>.</strong> $scoreboard[_i] 
				<</if>>
				
			<</for>>
			<<if _scoreFound is false>> <br><br>
				<<set _position to $scoreboard.indexOf($score)>>

				//You got rank _position ...not quite enough to make it to the top 10... :( <br>
				Better luck next time! //		
				
			<</if>>
		<</if>>
		
	<</widget>>

I’m displaying it in a passage like this:

:: time score [nobr]
	<h2>High Scores </h2>
<<updatescoreboard>>
<<scoreboard>>

The CSS is from here with minor adjustments: http://www.coding-dude.com/wp/css/highlight-text-css/

.circle-sketch-highlight{
  position:relative;
}.circle-sketch-highlight:before{
  content:"";
  z-index:-1;
  left:-0.5em;
  top:-0.1em;
  border-width:2px;
  border-style:solid;
  border-color:green;
  position:absolute;
  border-right-color:transparent;
  width:100%;
  height:1em;
  transform:rotate(2deg);
  opacity:0.7;
  border-radius:50%;
  padding:0.1.5em 0.3em;
}.circle-sketch-highlight:after{
  content:"";
  z-index:-1;
  left:-0.5em;
  top:0.1em;
  padding:0.1.5em 0.3em;
  border-width:2px;
  border-style:solid;
  border-color:green;
  border-left-color:transparent;
  border-top-color:transparent;
  position:absolute;
  width:100%;
  height:1em;
  transform:rotate(-1deg);
  opacity:0.7;
  border-radius:50%;
}