I love Achievements! [You received the 'Achievement feature suggestion' achievement] :)
Currently an admin that knows code can add achievements.
Would it be an idea to have achievements as Drupal Entities?
This way we would be able to
- use all available Drupal fields (for example achievement images as imagefields and apply image styles)
- allow non-code admins to create / edit Achievements through UI (easy upload of images, changing the image(field), name, description, Achievement message etc.
- create Views of Achievements
... more?
Comments
Comment #1
morbus iffI'm not sure this would work as nicely as you'd want: that is, code is always needed for an achievement to "do something." Any achievement building interface that supports Playskool achievement creation is always going to create cookie-cutter, similar, and decidedly unfun progression-based/grinding-only achievements. Whilst I can see the benefits of an interface to change achievement peculiars (title, image uploads, descriptions, etc.), as well as the ability to add new fields to it (tags or other oddities, etc.), none of that is particularly useful and can even be potentially confusing when a developer would still need to dip into the code to change the actual logic behind an achievement.
Comment #2
silkogelman commentedMaybe the programmer can provide the details through API and true/false the ability for the admin to edit the image/description in the UI.
Being able to change an image/description through UI (or apply an Image Preset on it) would be very nice.
For example it would be nice to have an imagefield if you want to be able to apply a 'Christmas border' image preset on all Achievement images in December, or just to be able to apply an image preset so you have a bit of control on how large the image shows on pc or mobile.
Comment #3
morbus iffs1l: Regarding image styling, I ran into a "biggish" problem the other day. Specifically, image styles only work on uploaded-through-the-UI images - that is, images that are stored in the public 'files' directory. Usually, I suspect, achievement images are stored alongside the implementing module and not in the 'files' directory. Thus, using image styles for achievements (which is a use case I wanted too!) is not really possible. For my client, I ended up using a dirty dirty hack which I've yet to figure out how to properly handle in the module.
Comment #4
ohthehugemanatee commentedI completely agree with your stance on shipping a play-skool UI for setting the requirements for an achievement. On the other hand, shipping with no UI and requiring a coder's knowledge of drupal hooks/PHP to set up achievements at all, is keeping this module from having more than 60 users. So there's a balance to be sought here. User Badges still doesn't have a D7 release candidate, and Achievements is a better conceived way to solve a very similar problem. If you find a good balance point, this module could see a lot more use.
It's important to figure out where the balance lies. Here's my 2c:
Why not separate the definition of the Achievement from the definition of the awarding conditions? Allow people to use Entity to define the basic elements of the Achievement such as title, description, and images... and even further customize it with other fields and information to suit their needs. Then say that you have to enter PHP logic for awarding the Achievement.
BETTER STILL, integrate with Rules AND custom PHP for awarding the Achievement. This way we really get best-of-both-worlds: extremely customizable and complex achievement conditions discourage "grinding" achievements. In fact, it encourages achievements that are linked to already-complex rules-based site behaviors like integration with a Commerce based web-store. But the module is still useful if you're not a PHP coder with deep knowledge of Drupal hooks. Actually, it would greatly ENHANCE the usefulness of the module, because you can take advantage of things like Drupal's image handling, content and file management structures, tokens, Features, backup-and-migrate, Views...
Integration with Rules and Entities would add enormous functionality to the module without much work. And there is no other module that provides this functionality at the moment - not even close.
Thoughts?
Comment #5
morbus iffJust as a quick reaction (more later, I suspect): I don't care about the number of users I have. I care about making the best code and design for a stated purpose: good, quality achievements that are not mind-numbingly not fun. I do not want 1000 more users to the module if it meant 1000 more sites with the same piece of crap achievements. Sorry, I'm just not gonna budge on that principle. I'm coming at achievements from a gamer's perspective, and I know of no "create-your-own" toolkit for achievements for World of Warcraft, Xbox 360, PlayStation 3, Steam, Kongregate, etc. All require the game developer (nee site developer) to intelligently and logically place an API hook where it is best applicable for a certain type of milestone.
Comment #6
morbus iffTo expand a little on the above: there are really "two" versions of "achievements" hanging around. There's the gamer-specific version (think Xbox 360 achievements, WoW achievements, PlayStation trophies, etc.) and there's the "badge" version (largely the purveyance of Web 2.0-type of sites like Gowalla, GetGlue, and Foursquare). User Badges is of the "Web 2.0" type. Achievements is of the Gamer type. User Points is another model entirely and is more infinite high-score than achievement/milestone.
The current high-end client of Achievements is focusing their end-user display on the Web 2.0 version of things. achievements.module, when implemented on their site (and yes, there'll be a case study once it launches), will look and act like a Web 2.0 approach instead of a gamer approach. It's perfectly possible for achievements.module to handle both types which is, ultimately, a matter of display and not code.
Regarding balance.
I don't see a huge difference between Scenario 1 (where user A uses a UI to define the achievement and user B uses code to initiate the unlock), Scenario 2 (where user A tells user B what strings to use), and Scenario 3 (where user B does everything). All require a coder at some point of the workflow, so creating a UI to satisfy the illusion of Playskooling an achievement is extra work for no real gain.
Note, however, Scenario 1 is currently possible *right now*. There is nothing stopping another developer from creating an achievements_ui.module that simply creates the hook_achievements_info() definitions from data entered via a UI. This module could also use theme preprocesses to implement image styles based on uploaded images (though, you'll need the forthcoming 1.4 to get an image_raw variable which I just added). The big problem would be allowing point changes - that would require some post-processing after the update, which would likely require a Drupal queue for large installations. Same with deletions (though, the module could likely use the forthcoming 1.4 achievements_locked() to first remove the deleted achievement from everyone.) Finally, there'd have to be a lot of cautioning that changing "Posted on a Monday" to "Posted twice on a Monday" requires a lot more than "just" a string change in the UI. Those are Workflow Problems that a UI introduces.
As for the other benefit of Entities, using custom Fields, that's currently also possible by just adding more keys in hook_achievements_info(). Yes, it's Not The Same thing, but it mimicks the solution decently enough. (With that said, the "Achievements are not Entities" is historical: the achievements.module started as Drupal 6, long before Entities were easily implemented. Also note that I don't actually know how to implement Entities yet, or all the benefits and detriments that come with that - got any docs?)
Similarly, there is nothing stopping a developer from creating an achievements_rules.module that allows integration therein too. I can't stop you if you want to do that. Be my guest! I also can't stop anyone from creating a contrib module that has hundreds of achievements already implemented, or a Feature that pre-implements the same hundreds of achievements.
There's a difference between specifically stopping someone from doing something and saying "you know what, here's *my* vision, but I can't stop you from doing yours either". I support the latter, of course. I have little interest, however, in going down the dangerous road of hating the implementation of my own module on other sites, which is why I'm primarily adverse to putting achievements_ui or achievements_rules in as base, and supported, modules.
Comment #7
silkogelman commentedI don't think Entity support, Rules integration
#1272240: Achievement Rules integration
image handling and Feature integration would compromise the fun/unique factors of an achievement.
It definitely not means achievements could only be mind numbing / repetitive because of those integrations.
In fact I dare to say it unlocks the ability to create more unique and fun achievements, it makes the Achievements module more flexible, more applicable in different scenarios.
As far as I can tell WoW, Steam, Xbox 360 etc all have an api available for their developers so that they can connect their custom code to a universal way of managing achievements.
In my opinion Rules and Entity integration could be the glue between Drupal code (or custom code) that triggers an achievement and the achievement module. (you can find Entity docs at the Entity module page, and here is some basic info.
In fact I believe the most flexible implementation for the Achievement module would be to create parts of it as an Achievement Feature (as in a Drupal Feature) like the Drupal Recipe module could be for example.
In my opinion currently the Achievement module tries to reinvent the wheel too much for some functionalities: we have very powerfull Drupal systems that we can 'unlock', why not make use of that power?
examples:
- Ranking users based on their achievements is way more flexible if it could be done through Views
- Badge Images should have the capability of Image Styles, and its madness to force a site admin to contact a programmer when he just wants to change an image or the style of an Achievement.
- functionality like informing the user of an achievement could be way more cool if we could connect it to a mobile push notifications like Prowl for example. Rules integration could enable those kinds of things.
Yes a programmer will probably create the achievement code that makes the unlock unique, fun and non repetitive.
Then let's enable him to dedicate his time to that, and not waste his time with site admin requests to change an image, change the leaderboard's field display, add the name of the user to the image, etc.
Drupal site admins (sometimes the client, sometimes a Drupal configuration expert) can do that by configuring other existing Drupal modules, so that the Achievement coder can focus on making the achievement code itself more cool.
Using an Entity + imagefield for storing basic achievement information (title, image etc) enables Views integration + image style capability, and it would enable people to do other stuff they can do with Entities like categorizing achievements, hide non-unlocked Achievements from the user, create various lists of stats (as block, on the user page etc.)
Morbus Iff's vision of achievements
I think Morbus Iff's vision on achievements is great, and I believe Entity, Rules & image field integration would fit perfectly this vision, it could complement, it could make it stronger, it could be the missing piece of a perfect puzzle: it fits the vision and it enables it to be applied in a more diverse scala of scenarios.
But that's just my 2 cents, maybe I'm just plain wrong. :)
So I suggest we put our heads together (and our coding + Drupal experience) and we 'unlock' achievement functionality for Drupal.
Comment #8
morbus iffExample #1: I do not necessarily believe that Views can do everything the underlying ranking currently does (that is, there are two types of ranks - a global rank and a per-achievement rank, and that information is available five or six different ways), relative ranking information that needs to calculate total ranks first, etc. I'm not a Views user myself (and the client I'm working with now does not and cannot use Views on their site, so it couldn't be a required module), so it is unlikely that I'll write up the Views code for it. However, like almost everything else being recommended, you're more than welcome to do it yourself already - there's nothing stopping you (besides, of course, the onus of "well, let's get Morbus to do it instead ;)).
Example #2: Per a previous comment, you're more than welcome to use image styles if the images are uploaded into the files/ directory somehow (and a developer, or UI, could push them there for you instead of storing them in a per-module directory). There's nothing stopping you from doing that right now in the current codebase, and it was actually something my primary client proposed (before we decided the cost to do so was more than simply automating the creation of the various images we need via a command line script).
Example #3: Already (theoretically) possible with hook_achievement_unlocked(). You wouldn't need Rules for it, of course, but, as above, you're more than welcome to create an achievements_rules.module that expands the module with Rules support. Like Views, I don't use Rules in any of my client sites (or myself), so forcing that to be a requirement to the Achievement module wouldn't sit well with my needs.
Note that I am also not a Features user, so Achievements will never require Features either.
I am, generally speaking, against requiring a lot of modules for Achievements to run - every module you mentioned above would cause Achievements to not be implementable on one of the largest Drupal 7 sites in existence (which just happens to be my client). Ideally, it comes down to pie-in-the-sky stuff: the above discussions seem pie-in-the-sky, but they also seem very, very optional to being in the base module- only Entity support really seems like something that MUST be included (and required).
To recap:
Comment #9
ohthehugemanatee commentedThanks for the considered responses... and your approach makes sense to me.
Maybe I'll take a crack at an achievements_ui module in my copious spare time. If I do, you can bet that it will come with 10 really stupid, grinding achievements. "you've logged in 50 times!" "you've commented 100 times!" . I'll see if I can make them EXTRA boring for you. (you've changed your email 10 times!).
ooooh, even better: "you've sent invitations to 400 friends!" If I'm going to include painful behavior in a module, I want it to produce spam, too!
Also, entities are pretty badass, it's worth learning them.
Comment #10
morbus iffSo, been reading about entities. Insert "/me sighs" already. The first big sigh came in the sense that all achievement info must now be stored in the database. This makes deployment more difficult (unless, of course, you're using import/export modules or Features, which we're not). One alternative would be to put them in an .install too (to keep them in code, in versioning, etc., which is a requirement on my end) which I suppose would be OK.
Comment #11
morbus iffAlso slightly concerned about the performance implications: on the user's page, we display (by default) ALL of the achievements in the system. If these become database records, we'd be looking at, under the best of circumstances, another SQL query for that page (to load in all the defined achievements). Since these will be run, presumably, through a greater node-like hook system (view, preprocess, etc.), it might slow down the page a bit. I probably couldn't cache them (as I do now) for fear of breaking cpde that wants to act on a "node-like thingy", where there is no caching on view or load.
Comment #12
Docc commentedUsing entities would be the "Drupal" way i guess.
Though mixed feelings here aswell.
I really like the clean way it is now. Fast, simple and most important in code.
Entities would blow things things up and worse, put it in the database. Wich is still a problem for Drupal in general (wich Features solves partial).
Though it can be put under versioning control with modules like http://drupal.org/project/entity or Features but thats a pain in the ass in my opinion.
But this is more of an Drupal core issue where talking about i guess. Entities would be the Drupal way as it is meant for data objects like this and this will open the door to module integrations wich you otherwise should create manually.
PS, Entities can be cached with: http://drupal.org/project/entitycache
Comment #13
ohthehugemanatee commentedThe problem with keeping information in the DB rather than code, is a core problem with all of Drupal... if not all CMSes in general. In making the choice to work with Drupal, we're choosing a system that keeps all the data in the DB, and that's that. IT is extra functionality to pull information from the DB and into code where a versioning system can get at it, and that is rightfully in a module (Features, broadly).
If your objective is to create a module that provides objective-based badges that are stored in code so they're accessible to your versioning system, that's fine. But unless that's a primary objective, IMHO it's better to go with the Drupal model and store things in the database.
Comment #14
morbus iff@ohthehugemanatee: Sorry, I will never buy that logic.
Comment #15
morbus iffComment #16
fizk commentedCheck out Achievements Views for Views integration.
Comment #17
fizk commentedCheck out Achievements Rules for Rules integration.
Comment #18
jhedstromAn interesting model for this mix between code-definition and Drupal entity system is the message module. All actions around messages are performed in code via hooks. Message *types* are configurable via a UI where fields can be added, and then they are exportable.
I'm currently attempting to create [message module] messages based on achievements, and this would be greatly simplified if achievements were, themselves, entities.
Comment #19
morbus iffFWIW, I'll be exploring Achievements as Entities after D8 is released and the docs catch up with reality.