• Achievements - Developer Friendly
    89 replies, posted
[b]Gmod Achievements[/b] Before I even start, yes I know there is already an achievements thing out there but this is different. [b]Features:[/b] - Serverside - Saves achievement progress to file based on player, using glon - Very easy to add new achievements - Each achievement has a class, with various player-related hooks - Derma-based GUI, look similiar to steam achievements - Easy to merge with your gamemodes (including Fretta, which I will suggest to Garry this is included with) - 2 achievement types - progress, and one-off - Category system [b]Evidence:[/b] [i]New screenshot of the GUI, showing 3 test achievements[/i] [img]http://www.fortfn.co.uk/images/Achievements_2.PNG[/img] [i]Screenshot of the GUI, showing 3 test achievements (OLD)[/i] [img]http://www.fortfn.co.uk/images/Achievements_1.PNG[/img] [i]The Lua file that sets up the achievements (shared) (NEW)[/i] [lua] include( "includes/modules/achievements.lua" ) AddCSLuaFile( "includes/modules/achievements.lua" ) require( "achievements" ) // achievements.EnableDebugMode( true ) achievements.CreateCategory( "AI Killing" ) local ACH = {} ACH.Type = ACHIEVEMENT_PROGRESS ACH.Description = "Kill 5 NPCs." ACH.Image = "gui/silkicons/bomb" ACH.Target = 5 function ACH:OnKilledNPC( ply, npc ) self:AwardPoint( ply ) end achievements.Register( "AI Killing", "AI Killer", ACH ) local ACH = {} ACH.Type = ACHIEVEMENT_PROGRESS ACH.Description = "Kill 10 NPCs." ACH.Image = "gui/silkicons/bomb" ACH.Target = 10 function ACH:OnKilledNPC( ply, npc ) self:AwardPoint( ply ) end achievements.Register( "AI Killing", "AI Owner", ACH ) local ACH = {} ACH.Type = ACHIEVEMENT_ONEOFF ACH.Description = "Play some chess." ACH.Image = "gui/silkicons/wrench" ACH.Target = 0 achievements.Register( "#misc", "Chess Play3r", ACH )[/lua] [i]The Lua file that sets up the achievements (shared) (OLD)[/i] [lua] include( "includes/modules/achievements.lua" ) AddCSLuaFile( "includes/modules/achievements.lua" ) require( "achievements" ) achievements.CreateCategory( "My Test" ) achievements.Register( "My Test", "Test Achievement", "This is a test achievement!", "gui/silkicons/wrench", ACHIEVEMENT_ONEOFF, {} ); achievements.Register( "My Test", "Test Achievement 2", "Get 10 kills!", "gui/silkicons/page", ACHIEVEMENT_PROGRESS, {} ); local ACH = {} function ACH:OnKilledNPC( ply, npc ) self:SetProgress( ply, self:GetProgress( ply ) + 10 ) end achievements.Register( "#gamemode", "AI Killer", "Kill 10 NPCs.", "gui/silkicons/bomb", ACHIEVEMENT_PROGRESS, ACH )[/lua] (Note, the test achievements are not functional but the AI Killer one is) Like I mentioned somewhere above, I will suggest to Garry that this is added to Fretta and perhaps Gmod itself, although I suspect the coding quality is probably too poor for the latter. No download yet, I have yet to tidy up all the code and comment it all. Post thoughts, suggestions etc.
Yay!
Very nice.
Looks delicious! Ooh, idea! What you could do is when the achievement is specified, loop through the functions attached to the ACH table... uh, let me show you! [lua] local function Register(category, name, description, icon, type, class) -- Stuff ^_^. if (class and type(class) == "table") then local k, v; for k, v in pairs(class) do if (type(v) == "function") then hook.Add(k, "achievement_"..category.."_"..name, function(...) class[k](class[k], ...); end); end; end; end; end; [/lua] That way, developers can easily use any hook! Food for thought ^_^.
Hmm very nice. Though, the point of the old addon being client side is that you can get achievements in any server.
[QUOTE=Nevec;14235464]Hmm very nice. Though, the point of the old addon being client side is that you can get achievements in any server.[/QUOTE] But this could be with the assumption that it's made to be customized in each server. Would be great for gamemodes.
[QUOTE=grea$emonkey;14235489]But this could be with the assumption that it's made to be customized in each server. Would be great for gamemodes.[/QUOTE] Yep, that's what the old one hardly had. I think.
For clientside achievements, people use the old one. (Which is perfectly fine, the old one is just as good as this one.) For gamemode developers, or ambitous server owners, they use this one.
[QUOTE=thomasfn;14235591]For clientside achievements, people use the old one. (Which is perfectly fine, the old one is just as good as this one.) For gamemode developers, or ambitous server owners, they use this one.[/QUOTE] I prefer a customized one for separate servers. Makes players wanna come back and play for something.
The progress bar should remain on attained achievements, instead of saying ATTAINED, which is pretty much assumed by the different color. Also, attained achievements should be bright, unattained ones should be dark.
[QUOTE=grea$emonkey;14235624]I prefer a customized one for separate servers. Makes players wanna come back and play for something.[/QUOTE] In which case, it is up to the server owners to customise it. In terms of adding achievements, it's easy - as you can see from the example code. Anything else (changing the Gui, etc) would involve editing the module.
[QUOTE=thomasfn;14235697]In which case, it is up to the server owners to customise it. In terms of adding achievements, it's easy - as you can see from the example code. Anything else (changing the Gui, etc) would involve editing the module.[/QUOTE] Making things modular is always good.
I'm a little shaky on the whole part where we need to add the progress manually. Can we define a target value on a progressive achievement and then add a value to it, instead of having to find the percents?
I think the pictures on the achievements look blocky and large. Otherwise good work.
Of course you'd need to provide your own images, the current icons are an obvious example.
The pictures on the achievements are placeholders, I used the silkicons (which are 32x32 pixels). The actual achievements will use proper 256x256 images. I added a target system, so you use self:AwardPoint() in the class to give a point and you define the target in the Register function. It still uses percentages backend, so you should make sure to use even targets.
Pretty nice, but it seems the progressbar is way too light. And 33.3333% =/= 34%.
Which progress bar, the green one, or the white achievement ones?
Add a "Show achieved" checkbox.
I changed the light background to mean attained, and the dark unattained. I also changed the bar to stay complete when a progress achievement is attained. Instead of defining everything in the Register function, you must now define in the table. (Examples shown below). [i]New screenshot[/i] [img]http://www.fortfn.co.uk/images/Achievements_2.PNG[/img] [i]The new table changes[/i] [lua] include( "includes/modules/achievements.lua" ) AddCSLuaFile( "includes/modules/achievements.lua" ) require( "achievements" ) // achievements.EnableDebugMode( true ) achievements.CreateCategory( "AI Killing" ) local ACH = {} ACH.Type = ACHIEVEMENT_PROGRESS ACH.Description = "Kill 5 NPCs." ACH.Image = "gui/silkicons/bomb" ACH.Target = 5 function ACH:OnKilledNPC( ply, npc ) self:AwardPoint( ply ) end achievements.Register( "AI Killing", "AI Killer", ACH ) local ACH = {} ACH.Type = ACHIEVEMENT_PROGRESS ACH.Description = "Kill 10 NPCs." ACH.Image = "gui/silkicons/bomb" ACH.Target = 10 function ACH:OnKilledNPC( ply, npc ) self:AwardPoint( ply ) end achievements.Register( "AI Killing", "AI Owner", ACH ) local ACH = {} ACH.Type = ACHIEVEMENT_ONEOFF ACH.Description = "Play some chess." ACH.Image = "gui/silkicons/wrench" ACH.Target = 0 achievements.Register( "#misc", "Chess Play3r", ACH )[/lua] There are a few default categories as well, these are: #gamemode - Shows up as the gamemode's name on the gui. #misc - Shows up as 'Uncategorised' #all - You musn't add achievements to this, you will get duplicates. An achievement may be in multiple categories.
Are there any notices to show when a player attained an achievement?
[QUOTE=Nerdboy;14237402]Are there any notices to show when a player attained an achievement?[/QUOTE] Yes. A message is broadcast to the whole server, saying "Nerdboy has achieved 'AI Killer'!" or something like that. A little box in the corner of the screen also pops up on the client (only whoever achieved it, not the whole server :P) saying "AI Killer Achieved!". [b]Edit:[/b] Added a "Show Achieved" checkbox. If you close achievements window and reopen it, it will save the checkbox but it won't save over disconnects.
Sorry for the double post. Added a way to hook ANY gamemode hook into the system: [code]achievements.AddCustomHook( "PlayerSay" )[/code] Then, on your class: [code]function ACH:PlayerSay( ply, text ) self.Data = ply.A_DATA // DO ACHIEVEMENT STUFF HERE self.Data = nil end[/code] You will only be able to use hooks where the player is defined. Otherwise, you can't get achievement data from anywhere. If self.Data isn't defined, none of the functions (self:SetProgress, self:AwardPoint etc) will work.
Triple post o.O Ok, I released this since I don't think I'm going to get more work done on it. [url=http://www.garrysmod.org/downloads/?a=view&id=65278][img]http://www.garrysmod.org/img/?t=dll&id=65278[/img][/url] There is an included sample file, and a quick reference manual. Note, this has NOT been tested in a multiplayer enviroment since I never got round to it. It works perfect in singleplayer. There's no reason it shouldn't work in multiplayer though, I designed it to work for multi. Please remember this is more aimed at server owners + gamemode developers, not the average player. [b]This is not an addition to, replacement of or in any way linked to the other clientside achievements thing - NO code has been copied whatsoever. In fact, I didn't even look at the other addon's code.[/b]
Okay. So this is some kind of Module to help make achievements or achievement addons? Edit: Okay..Re-Reading..and now I understand.
[QUOTE=thomasfn;14320649]blah release blah[/QUOTE] Holy shit, I've got awesome ideas for this
I'm confused. How would I get this to be able to count like How many times I killed someone. One of the Hooks is Move...which means it detects when someone moves or how much someone has moved?
So, we can hook an event to an achievement? like "OnNPCKilled"? Also, can you call functions when an achievement is achieved? For EX: A gamemode has a money stem that uses NWInts. Can you use this to call a function for things such ass awarding prize money? That's just in my case... Also, gamemode developers ARE allowed to use this in their gamemode, correct?
Yes, anyone can use the module for any purpose so long as the credits at the top of the module remain intact. You can hook any event to the class, and you can use achievements.Call to call a function on all achievements. (If a function doesn't exist on an achievement, it will skip it.) OnNPCKilled is hooked by default, as is Move (it will use the same parameters as the gamemode hook).
Well done thomas! I didn't really like the past achievements thing, plus this will be a great addition to servers, it's like TF2 in GMod :D, brilliant!
Sorry, you need to Log In to post a reply to this thread.