Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Achievements #126

Open
gabssss opened this issue Jan 25, 2018 · 8 comments
Open

Idea: Achievements #126

gabssss opened this issue Jan 25, 2018 · 8 comments

Comments

@gabssss
Copy link

gabssss commented Jan 25, 2018

I'd love to know how to implement Achievements.

For example:

  • You created your first thread!
  • You created a thread 10 times!
  • You replied to threads 100 times!
  • Your replies got selected as best reply 10 times!
  • You uploaded your profile picture!
  • You favorited replies 50 times!

I have a lot of doubts in how it would be implemented, for example:

  • Using events/listeners to check if the user got any achievement, every time an action is done (for example thread posted, reply posted, etc), would it make the requests slow?
  • Checking replies count, or favorites count, wouldn't it be a slow/heavy query? Should I use redis for this (I have no idea when to use Redis).

Would be really nice if someone experienced could implement this so newbies like me could understand the logic behind it!

@chrisbbreuer
Copy link

How I would most likely approach it is to create additional columns thread_count, reply_count, favorite_count and best_reply_count (I forgot, do we have already a way to track best replies?) on the user model and then when a incrementing action happens, check if an achievement is achieved, which simply can be stored in the council config file.

Obviously, maybe not most appropriate for uploading a profile picture.

It seems the easiest approach to me - not sure if it's the best, considering my Redis experience is really close to non-existent, but from what I hear, it could be a good use case for this haha

@MattMangoni
Copy link
Contributor

We can just use withCount() to get the number of replies, threads, and any other related model we defined for the user. This will give you access to “threads_count”, “replies_count” etc from the user collection without adding any column to the db. Or maybe we can just get the count, if that’s more appropriate :)

That part is not a problem at all :)

@MattMangoni
Copy link
Contributor

MattMangoni commented Jan 25, 2018

But yeah, this would benefit from using Redis a lot, imho.
And since we will end up with a lot of duplication and more than one task after each user interaction (at least registering the reputation gain and this) we could refactor and think about using events.

@GuillaumeValadas
Copy link

And maybe achievements can add some reputation points.

But people could flood threads/replies only for get the achievements ?

@Diddyy
Copy link

Diddyy commented Jan 30, 2018

@gabssss Was having a look at https://github.com/gstt/laravel-achievements maybe if we could produce something like that. They use two event listeners 'AchievementProgress' and 'AchievementUnlocked' seems like a good approach to me. I may have a play with this when I have some free time and see if I can get a PR sorted.

@gabssss
Copy link
Author

gabssss commented Jan 30, 2018

@Diddyy this package is really nice, loved it.

But I came up with another question... Wouldn't one class for each achievement make a lot of files as the application grows?

For example, if I want to give an achievement for each multiples of 10 replies created, I'd have to create a lot of files... Or if I want to have an achievement "5 threads created in the X channel", I'd also have to create it to each channel, and if I want to have in addition to 5 threads, 10 and 15 also, multiply the created files by three and so on...

Any ideas in this matter would be really appreciated.


What I'm thinking is having a "currency" (like reputation) for each "action" a user can do:

  • threads_created
  • replies_posted
  • best_replies
  • thread_created_in_the_x_channel
  • etc.

Then, events for each of them, to increase or decrease (the channels one would be just one event, and it would attach the channel name or id as a variable to the currency name, so no duplication).

A "achievements" table, in which achievements can be created in an admin panel, by selecting one or more currencies (and for which it'd need a achievement_currency pivot table) and the needed points to unlock it.

And a "achivement_user" table to place the unlocked ones, and maybe progress so we don't have to keep rechecking the currencies? But it would be sort of duplicated information.

I don't know if it's the best approach...

@Diddyy
Copy link

Diddyy commented Jan 30, 2018

@gabssss I like your idea of how to set it out using "achievements" and "achievement_user" table that is the approach I would look at doing also. The package I only came across today and read it quickly and I agree, I don't believe having a class for each achievement.

Will try to do an approach like you explained soon, will be interesting to see how it will turn out!

@gabssss
Copy link
Author

gabssss commented Jan 30, 2018

I'm glad you liked my idea @Diddyy !
I wish I had the confidence and knowledge to try to implement it and start doing PRs and such.


Came up with another question on how it'd work... About the "thread_created_in_the_x_channel" currency, what if the thread belongs to a channel, but then an admin changes it to another channel?

And what about if channels were tags, it looks like it'd create a lot of redundancy in the currencies table with all the "thread_created_in_the_x_tag" ones. Specially if the application grows to a state where it'd possess hundreds of tags.

That's why I don't even try it.. Every time I think I have a nice idea, doubts came up that make it impossible.. :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants