diff --git a/conf/config.yaml b/conf/config.yaml
index 7cce32b7cfbe6f63ceeb297d119365d415f07d0c..f283bb0e175f5a3f9b1bd1186e3d5246780747b1 100644
--- a/conf/config.yaml
+++ b/conf/config.yaml
@@ -9,7 +9,7 @@
 :restart_delay: 10
 :address: 0.0.0.0
 :intro_file: intro.txt
-:start_room: 925f8042-915a-9582-2d07-059473ae02f7
+:start_room: 136a3824-e27a-67d0-bfe0-292f070de261
 :restart_limit: 15
 :mccp: false
 :mssp: false
diff --git a/lib/aethyr/core/commands/help_handler.rb b/lib/aethyr/core/commands/help_handler.rb
index a1954394e644c786049db1adbc1025271e05aa2e..3b056c5c915deaa4b198a3495da8403099caaa05 100644
--- a/lib/aethyr/core/commands/help_handler.rb
+++ b/lib/aethyr/core/commands/help_handler.rb
@@ -9,15 +9,9 @@ module Aethyr
         super(player, *args)
 
         @commands = commands
-      end
 
-      def player_input(data)
-        super(data)
-        case data[:input]
-        when /^(help|help topics)$/i
-          if self.can_help?
-            self.player.output( commands, false)
-          end
+        help_entries.each do |entry|
+          player.help_library.entry_register entry
         end
       end
 
diff --git a/lib/aethyr/core/help/help_entry.rb b/lib/aethyr/core/help/help_entry.rb
index 86302c63c29bc48f96b4d26ea2968f5e70811633..bcc78c863a69553826dceae2f121da41f81d2e44 100644
--- a/lib/aethyr/core/help/help_entry.rb
+++ b/lib/aethyr/core/help/help_entry.rb
@@ -2,16 +2,16 @@ module Aethyr
   module Core
     module Help
       class HelpEntry
-        attr_reader :redirect, :content, :see_also, :command, :aliases
+        attr_reader :topic, :redirect, :content, :see_also, :aliases
 
-        def initialize(command, redirect: nil, content: nil, see_also: nil, aliases: nil, syntax_formats: nil)
+        def initialize(topic, redirect: nil, content: nil, see_also: nil, aliases: nil, syntax_formats: nil)
           #do some validity checking on the arguments
-          raise "Command can not be nil" if command.nil?
+          raise "Topic can not be nil" if topic.nil?
           raise "Redirect cant be defined alongside other arguments" unless redirect.nil? || (content.nil? && see_also.nil? && aliases.nil? and syntax_formats.nil?)
           raise "either content or redirect must be defined" if redirect.nil? && content.nil?
           raise "syntax_format must be defined when content is defined" if (not content.nil?) && (syntax_formats.nil? || syntax_formats.empty?)
 
-          @command = command
+          @topic = topic
           @redirect = redirect
           @content = content
           @see_also = see_also
@@ -20,6 +20,10 @@ module Aethyr
           @see_also = [] if @see_also.nil? && (not @content.nil?)
           @aliases = [] if @aliases.nil? && (not @content.nil?)
         end
+
+        def redirect?
+          return (not @redirect.nil?)
+        end
       end
 
     end
diff --git a/lib/aethyr/core/help/help_library.rb b/lib/aethyr/core/help/help_library.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ff1ec27ec1a4a8ca734f62a6d0d3578f821f72ed
--- /dev/null
+++ b/lib/aethyr/core/help/help_library.rb
@@ -0,0 +1,60 @@
+# coding: utf-8
+module Aethyr
+  module Core
+    module Help
+      class HelpLibrary
+        def initialize
+          @help_registry = {}
+        end
+
+        def entry_register(new_entry)
+          pp new_entry
+          pp @help_registry
+          @help_registry[new_entry.topic] = new_entry
+        end
+
+        def entry_deregister(topic)
+          @help_registry.delete(topic)
+        end
+
+        def search_topics(search_term)
+          return @help_registry.keys.grep /#{search_term}/
+        end
+
+        def topics
+          return @help_registry.keys.dup
+        end
+
+        def lookup_topic(topic)
+          return @help_registry[topic]
+        end
+
+        def render_topic(topic)
+          redirected_from = ""
+          entry = lookup_topic(topic)
+          while entry.redirect? do
+            redirected_from = "→ redirected from #{topic}\n\n" if redirected_from.empty?
+            entry = lookup_topic(entry.redirect)
+          end
+
+          rendered = redirected_from
+
+          rendered += "Aliases: " + entry.aliases.join(", ") + "\n" unless aliases.empty?
+
+          syntaxes = []
+          entry.syntax_formates.each do |syntax|
+            syntaxes.push "Syntax: #{syntax}"
+          end
+          rendered += syntaxes.join("\n")
+          rendered += "\n" unless syntaxes.empty? && aliases.empty?
+
+          rendered += entry.content + "\n"
+
+          rendered += "See also: " + emtry.see_also.join(", ") + "\n" unless see_also.empty?
+
+          return rendered
+        end
+      end
+    end
+  end
+end
diff --git a/lib/aethyr/core/objects/player.rb b/lib/aethyr/core/objects/player.rb
index 41bd411314c6e7e10341523d2103d3396416eb69..885e98100bfc7f9e2eb54b1ca21d54ca3fccc02e 100644
--- a/lib/aethyr/core/objects/player.rb
+++ b/lib/aethyr/core/objects/player.rb
@@ -4,6 +4,7 @@ require 'aethyr/core/help/syntax'
 # TODO : Delete the next to requires
 require 'aethyr/extensions/skills/map'
 require 'aethyr/extensions/skills/kick'
+require 'aethyr/core/help/help_library'
 
 #Base class for all players.
 class Player < LivingObject
@@ -39,7 +40,7 @@ class Player < LivingObject
 
   }
 
-  attr_reader :admin, :color_settings
+  attr_reader :admin, :color_settings, :help_library
   attr_accessor :use_color, :reply_to, :page_height
 
   #Create a new player object with the given socket connection. You must also pass in a game_object_id and a room, although if you pass in nil for game_object_id it will auto-generate one for you.
@@ -58,6 +59,7 @@ class Player < LivingObject
     @reply_to = nil
     @prompt_shown = false
     @player.display.layout(layout: :basic)
+    @help_library = Aethyr::Core::Help::HelpLibrary.new
 
     info.stats.satiety = 120
     map_skill = Aethyr::Extensions::Skills::Map.new(self.game_object_id)