Achievements by Juhana Leinonen

This topic is for discussions related to Achievements by Juhana Leinonen.

1 Like

I’m getting a HTTP 403 forbidden error when I try to download this extension.

1 Like

I’m using the ā€œpersistent achievementsā€ option, but I’ve found that when an achievement gets awarded on a game-ending turn, using ā€œundoā€ erases that achievement from the list of achievements the player has earned (meaning Inform must be erasing the achievement from the external file). Is there a way to make Inform not erase these achievements? I’d like them to remain on the player’s ā€œearned achievementsā€ list, even if the player uses undo.

1 Like

Having just rolled my own persistent achievement system, my guess is that the achievement is being saved to the external file, but that the game isn’t loading those achievements after an undo. There’s no need to load achievements from the file every turn; loading them when game starts may be the only time it happens. For me, I’m using Undo Output Control, and with that, I could do:

After undoing an action:
	load achievements;

where ā€˜load achievements’ reads the achievements in from a file. Maybe you could do something similar?

5 Likes

As Lucian said, I think the achievement is not erased from the external file. If you restart the game, you can use the achievements command to see that they have all been re-read from the file, which should include the one which appeared to be undone. You can also open the achievementdata.glkdata file in a text editor and check that it remains recorded.

I think the issue is partly due to the way UNDO behaves. As far as I know, it works by basically restoring the state of the entire virtual machine (VM) to how it was before the previous turn. So, as far as any variables and achievements in the current run of the game are concerned, the last turn never happened.

There are probably various ways to solve the problem.

One way would be something like: After undoing, restore the Table of Achievements from the external file. But there is no direct/builtin way to make an ā€œAfter undoingā€ rule, without using extensions like Undo Output Control, due to the way that UNDO works, as mentioned above. (For the VM, UNDOing never happened.)

What I’ve tried instead [EDIT: but I came back to the ā€œafter undoingā€ solution again, see further below] is to restore the achievements from the file when the player enters the achievements command (during the game or at the final options prompt). For the restoration part, I used the same code which the extension itself uses when starting a game.

So, here’s a small example:

Include Achievements by Juhana Leinonen.

Use persistent achievements.

The Lab is a room.

Table of Achievements
achievement	description	validation (a rule)	awarded
"Waving"	"You waved."	--	false
"Exiting"	"You exited the lab."	--	false

Last report waving hands:
	award the "Waving" achievement;

Instead of exiting:
	say "You exit the lab.";
	award the "Exiting" achievement;
	end the story finally;

First carry out listing achievements when the persistent achievements option is active (this is the restore data from file rule):
	now loadingstate is true;
	let data be text;
	let name be text;
	let checksum be text;
	let mode be "name";
	if the file of Persistent Achievements exists:
		now data is "[text of the file of Persistent Achievements]";
		repeat with C running from 1 to the number of characters in data:
			if character number C in data is "|":
				if mode is "checksum":
					if checksum is "[checksum for name]":
						[the checksum was correct, award the achievement]
						award the name achievement, silently;
					now mode is "name";
					now name is "";
					now checksum is "";
				otherwise if mode is "name":
					now mode is "checksum";
			otherwise if mode is "name":
				now name is "[name][character number C in data]";
			otherwise if mode is "checksum":
				now checksum is "[checksum][character number C in data]";
	now loadingstate is false.

Before printing the player's obituary when the persistent achievements option is active:
	follow the restore data from file rule.
	
Before listing final achievements when the persistent achievements option is active:
	follow the restore data from file rule.

Results:

Lab

>wave
You wave.

[Achievement unlocked: Waving]

(Command ACHIEVEMENTS to see a list of your achievements.)

>undo
Lab
[Previous turn undone.]

>exit
You exit the lab.
[Achievement unlocked: Exiting]

*** The End ***

You unlocked 2 achievements out of 2.

Would you like to RESTART, RESTORE a saved game, QUIT, UNDO the last command or list your ACHIEVEMENTS?
> undo
Lab
[Previous turn undone.]

>achievements
You have unlocked the following achievements:

Waving: You waved.
Exiting: You exited the lab.

I’ve tested this a bit, albeit not super-extensively, but it should be a good start, I think.

Combining it with an extension like Undo Output Control, as mentioned above, so that you can just re-read the file after an UNDO, is probably a good idea, because otherwise, if the player entered ā€œWAVE / UNDO / WAVEā€, for example, the message ā€œ[Achievement unlocked: Waving]ā€ would be displayed twice.

Edited again to add:
In the code above, I copied the relevant rule from the extension, to make explicit what it does, and because I thought I might want to change stuff as I experimented.
But that’s not necessary, and it’s shorter and clearer to just refer to the named rule from the extension directly.
So, re-using the rule and combining it with the Undo-extension, we should be able to achieve the intended results by just doing this:

Include Achievements by Juhana Leinonen.
Include Undo Output Control by Nathanael Nerode.

Use persistent achievements.

After undoing an action:
	now loadingstate is true;
	follow the read achievement data from an external file rule;
6 Likes

This is working perfectly—thank you!

2 Likes