The Blog

Feb 25
0

Meta Leaderboards

by David Czarnecki

Categories

Traditionally, leaderboards rank players using one criteria, e.g. XP, kills, etc. What if you wanted to retrieve information from a leaderboard that combined more than one criteria? I’m going to show you how to do that.

To be honest, I don’t necessarily have a definite use case for this functionality, but I thought it might be useful. So, here goes nothing.

Let’s say you’ve got a game and its multiplayer mode can be played across 5 maps. We’ll also simplify things and say that we’re only ranking players on each map on XP gained when finishing the map. If you want to generate a leaderboard of players ranked by XP who have played in any of the maps, you would need to perform a merge of each of the leaderboards for the 5 maps. If you want to generate a leaderboard of players ranked by XP who have played in each of the maps, you would need to perform an intersection of each of the leaderboards for the 5 maps.

This functionality is now present in the Ruby leaderboard gem released today.

You can use the merge_leaderboards(…) call to merge the current leaderboard with any other leaderboards into a new leaderboard.

ruby-1.8.7-p302 > map_1_xp_lb = Leaderboard.new('map_1_xp')
 => #<Leaderboard:0x1018d96e8 @leaderboard_name="map_1_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_2_xp_lb = Leaderboard.new('map_2_xp')
 => #<Leaderboard:0x1018d3568 @leaderboard_name="map_2_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_3_xp_lb = Leaderboard.new('map_3_xp')
 => #<Leaderboard:0x1018cd460 @leaderboard_name="map_3_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_4_xp_lb = Leaderboard.new('map_4_xp')
 => #<Leaderboard:0x1018c7358 @leaderboard_name="map_4_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_5_xp_lb = Leaderboard.new('map_5_xp')
 => #<Leaderboard:0x1018c1250 @leaderboard_name="map_5_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_1_xp_lb.add_member('member_1', 10)
 => true
ruby-1.8.7-p302 > map_2_xp_lb.add_member('member_2', 7)
 => true
ruby-1.8.7-p302 > map_3_xp_lb.add_member('member_3', 7)
 => true
ruby-1.8.7-p302 > map_4_xp_lb.add_member('member_4', 22)
 => true
ruby-1.8.7-p302 > map_5_xp_lb.add_member('member_5', 3)
 => true
ruby-1.8.7-p302 > map_1_xp_lb.merge_leaderboards('all_maps_xp_lb', ['map_2_xp', 'map_3_xp', 'map_4_xp', 'map_5_xp'])
 => 5
ruby-1.8.7-p302 > all_maps_xp_lb = Leaderboard.new('all_maps_xp_lb')
 => #<Leaderboard:0x101883040 @leaderboard_name="all_maps_xp_lb", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > all_maps_xp_lb.total_members
 => 5
ruby-1.8.7-p302 > all_maps_xp_lb.leaders(1)
 => [{:rank=>1, :member=>"member_4", :score=>22.0}, {:rank=>2, :member=>"member_1", :score=>10.0}, {:rank=>3, :member=>"member_3", :score=>7.0}, {:rank=>4, :member=>"member_2", :score=>7.0}, {:rank=>5, :member=>"member_5", :score=>3.0}]

view raw gistfile1.txt This Gist brought to you by GitHub.

You can use the intersect_leaderboards(…) call to intersect the current leaderboard with any other leaderboards into a new leaderboard.

ruby-1.8.7-p302 > map_1_xp_lb = Leaderboard.new('map_1_xp')
 => #<Leaderboard:0x1018d96e8 @leaderboard_name="map_1_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_2_xp_lb = Leaderboard.new('map_2_xp')
 => #<Leaderboard:0x1018d34f0 @leaderboard_name="map_2_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_3_xp_lb = Leaderboard.new('map_3_xp')
 => #<Leaderboard:0x1018cd370 @leaderboard_name="map_3_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_4_xp_lb = Leaderboard.new('map_4_xp')
 => #<Leaderboard:0x1018c71f0 @leaderboard_name="map_4_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_5_xp_lb = Leaderboard.new('map_5_xp')
 => #<Leaderboard:0x1018c1070 @leaderboard_name="map_5_xp", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > map_1_xp_lb.add_member('member_1', 10)
 => false
ruby-1.8.7-p302 > map_1_xp_lb.add_member('member_2', 19)
 => true
ruby-1.8.7-p302 > map_2_xp_lb.add_member('member_2', 7)
 => false
ruby-1.8.7-p302 > map_3_xp_lb.add_member('member_3', 7)
 => false
ruby-1.8.7-p302 > map_3_xp_lb.add_member('member_4', 17)
 => true
ruby-1.8.7-p302 > map_4_xp_lb.add_member('member_4', 22)
 => false
ruby-1.8.7-p302 > map_4_xp_lb.add_member('member_5', 2)
 => true
ruby-1.8.7-p302 > map_5_xp_lb.add_member('member_5', 3)
 => false
ruby-1.8.7-p302 > map_5_xp_lb.add_member('member_1', 13)
 => true
ruby-1.8.7-p302 > map_1_xp_lb.merge_leaderboards('intersect_maps_xp_lb', ['map_2_xp', 'map_3_xp', 'map_4_xp', 'map_5_xp'])
 => 5
ruby-1.8.7-p302 > intersect_maps_xp_lb = Leaderboard.new('intersect_maps_xp_lb')
 => #<Leaderboard:0x10188a890 @leaderboard_name="intersect_maps_xp_lb", @page_size=25, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.3)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
ruby-1.8.7-p302 > intersect_maps_xp_lb.total_members
 => 5
ruby-1.8.7-p302 > intersect_maps_xp_lb.leaders(1)
 => [{:rank=>1, :member=>"member_4", :score=>39.0}, {:rank=>2, :member=>"member_2", :score=>26.0}, {:rank=>3, :member=>"member_1", :score=>23.0}, {:rank=>4, :member=>"member_3", :score=>7.0}, {:rank=>5, :member=>"member_5", :score=>5.0}]

view raw gistfile1.txt This Gist brought to you by GitHub.

Hopefully you’ll find this functionality useful.

You can find more hilarity over on my Twitter account, CzarneckiD.

  • Reddit
  • Digg
  • del.icio.us
  • Facebook
  • Tumblr
  • Twitter

Leave a Reply

*