T4 Modules Howto Guide/Achievements
Work in progress. Not yet finished or tested.
Adding the World
T-Engine uses the WorldAchievements interface to track and grant achievements and stores achievements as part of the World object. To add these to your own module:
Add a World.lua file in your class directory. Sample contents (based on ToME's):
require "engine.class" require "engine.World" require "engine.interface.WorldAchievements" local Savefile = require "engine.Savefile" module(..., package.seeall, class.inherit(engine.World, engine.interface.WorldAchievements)) function _M:init() engine.World.init(self) end function _M:run() self:loadAchievements() end --- Requests the world to save function _M:saveWorld(no_dialog) -- savefile_pipe is created as a global by the engine savefile_pipe:push("", "world", self) end
Change load.lua to create a World object as well as a Game object. To do so, edit the last line. It should look something like this:
return { require "mod.class.Game" }
Replace it with this:
return { require "mod.class.Game", require "mod.class.World" }
Defining Achievements
Under your module's data directory, create an achievements directory. Create as many .lua files defining achievements within this directory as you like; each .lua file should call the T-Engine newAchievement function for each achievement to be created.
Here's a sample, based on ToME itself:
newAchievement{ name = "Pyromancer", desc = [[Unlocked Archmage class and did over one million fire damage (with any item/talent/class).]], show = "full", mode = "world", can_gain = function(self, who, dam) self.nb = (self.nb or 0) + dam return self.nb > 1000000 and profile.mod.allow_build.mage end, track = function(self) return tstring{tostring(math.floor(self.nb or 0))," / 1000000"} end, on_gain = function(_, src, personal) game:setAllowedBuild("mage_pyromancer", true) local p = game.party:findMember{main=true} if p.descriptor.subclass == "Archmage" then if p:knowTalentType("spell/wildfire") == nil then p:learnTalentType("spell/wildfire", false) p:setTalentTypeMastery("spell/wildfire", 1.3) end end end, }
Parameters for newAchievement:
Parameter | Description |
---|---|
name | Name of the achievement |
id | Internal ID of the achievement. Optional. If not provided, then name will be used, uppercased and with spaces replaced with underscores. |
desc | Full description |
image | Optional filename for the achievement |
mode | "world", "game", "player", or "none". Indicates whether the achievement is tracked for the persistent World object, the game object, or the current player. For example, achievements that can only be gained once ever should be world achievements, while per-character achievements should be player. |
huge | If true, this achievement is a big deal and gets some extra emphasis when announced. |
show | Determines how this achievement is listed in the default ShowAchievements dialog:
|
no_chat_broadcast | If provided and true, then don't broadcast to the in-game chat when this achievement is gained. |
can_gain | Optional function, taking (data, src, ...) arguments (where ... is whatever additional arguments were passed to gainAchievement or gainPersonalAchievement), to be called to check whether the achievement can be gained. data is the persistent achievement data: either world.achievement_data, game.achievement_data, or player.achievement_data, depending on mode. |
track | Optional function, taking (data, src) arguments, giving progress towards the achievement (for display in the ShowAchievements dialog). Should return a tstring. |
on_gain | Optional function, taking (self, src, personal) arguments (where self is the achievement definition), to be called when an achievement is gained. |
Once you're finished, add code to your load.lua to load the achievements.
local WorldAchievements = require "engine.interface.WorldAchievements" WorldAchievements:loadDefinition("/data/achievements/")
Showing Achievements
In your Game.lua, you most likely have a call to engine.dialogs.GameMenu, where you pass in a list of menu items for the in-game main menu. Add "achievements" to the list of items here. Then, pressing Esc within the game will include a "Show Achievements" item where you can see the achievements you've defined and whether or not you've received them yet.