<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,2 +1,3 @@
 log/*
 tmp/*
+doc/*</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 = Autumn: A Ruby IRC Bot Framework
-&lt;b&gt;Version 2.0.3 (Mar 22, 2008)&lt;/b&gt;
+&lt;b&gt;Version 3.0 (Jul 4, 2008)&lt;/b&gt;
 
 Author::    Tim Morgan (mailto:riscfuture@gmail.com)
 Copyright:: Copyright (c)2007-2008 Tim Morgan
@@ -22,8 +22,10 @@ command line in order to run Autumn.
 If you wish to use a database backend for your bot, you will need the DataMapper
 gem. To install, see the DataMapper website (http://www.datamapper.org).
 
-The included example bot, Scorekeeper, requires the DataMapper gem. It can
-optionally use the Chronic gem to enhance its textual date parsing.
+The included example bot Scorekeeper requires the DataMapper gem. It can
+optionally use the Chronic gem to enhance its textual date parsing. The other
+example bot, Insulter, is much simpler and can run under any Autumn
+configuration.
 
 == Directory Structure
 
@@ -33,7 +35,7 @@ seem confusing to people who have never used Autumn before, but bear with me. In
 a bit I will explain in detail what all of this stuff is. For now, here is an
 overview you can consult for future reference:
 
-* &lt;b&gt;config/&lt;/b&gt; - Configuration files and
+* &lt;b&gt;config/&lt;/b&gt; - Configuration files and season definitions
   * global.yml - Universal settings that apply to every season
   * &lt;b&gt;seasons/&lt;/b&gt; - Contains directories for each season (see &quot;Seasons&quot;)
     * &lt;b&gt;testing/&lt;/b&gt; - Example season
@@ -41,13 +43,21 @@ overview you can consult for future reference:
       * leaves.yml - Example bot configuration file
       * season.yml - Season configuration
       * stems.yml - Example IRC configuration file
-* &lt;b&gt;data/&lt;/b&gt; - Not used by the program, but you can store your SQLite database
-  files here.
 * &lt;b&gt;doc/&lt;/b&gt; - HTML documentation generated by RDoc
   * &lt;b&gt;api/&lt;/b&gt; - Autumn API documentation
   * &lt;b&gt;leaves/&lt;/b&gt; - Autumn leaves documentation
-* &lt;b&gt;leaves/&lt;/b&gt; - Autumn::Leaf subclasses
-  * scorekeeper.rb - Example leaf provided with the installation
+* &lt;b&gt;leaves/&lt;/b&gt; - Autumn leaves. Each subdirectory contains all the code and
+  data for a leaf.
+  * &lt;b&gt;insulter/&lt;/b&gt; - Very simple example leaf
+    * &lt;i&gt;See the *scorekeeper* directory&lt;/i&gt;
+  * &lt;b&gt;scorekeeper/&lt;/b&gt; - Database-backed, full-featured example leaf
+    * config.yml - Optional leaf-global configuration options
+    * controller.rb - The leaf's controller object
+    * &lt;b&gt;data/&lt;/b&gt; - Optional directory for data storage (not used by Autumn)
+    * &lt;b&gt;helpers/&lt;/b&gt; - Modules that extend the controller and views
+    * &lt;b&gt;models/&lt;/b&gt; - Active record-type database objects
+    * &lt;b&gt;tasks&lt;/b&gt; - Additional rake tasks for this leaf
+    * &lt;b&gt;views/&lt;/b&gt; - ERb views for each of the leaf's commands
 * &lt;b&gt;libs/&lt;/b&gt; - Autumn core code
   * channel_leaf.rb - A leaf subclass that can ignore messages from certain
     channels its in
@@ -80,13 +90,13 @@ overview you can consult for future reference:
   * destroy - Destroys Autumn objects
   * generate - Creates Autumn objects
   * server - Starts Autumn
-* &lt;b&gt;support/&lt;/b&gt; - Additional code your bots need
+* &lt;b&gt;shared/&lt;/b&gt; - Shared code libraries available to all leaves
 * &lt;b&gt;tmp/&lt;/b&gt; - Temporary files, such as PID files
 
 == Configuring Autumn for Your First Launch
 
-Before you can run Autumn and try out the example leaf, Scorekeeper, you'll need
-to set up a few things. Here are the steps:
+Before you can run Autumn and try out the example leaves, you'll need to set up
+a few things. Here are the steps:
 
 === Configure Your Testing Season
 
@@ -102,9 +112,9 @@ information, see &quot;Stems&quot; below.
 Next, edit the database.yml file. As mentioned previously, Scorekeeper requires
 the DataMapper gem because it uses a persistent store. By default it's set up to
 use a MySQL database, but you can use PostgreSQL or SQLite 3 if you'd like. If
-you'd prefer not to install any of these database solutions, please skip to
-&quot;Making Your Own Leaf,&quot; below, disable the Scorekeeper leaf, delete the
-database.yml file, and then continue from here.
+you'd prefer not to install any of these database solutions, delete the
+database.yml file and remove the Scorekeeper leaf from the leaves.yml and
+stems.yml files.
 
 Lastly, view the leaves.yml file. You shouldn't have to make any changes to this
 file, but it's a good idea to look at it to see how leaves are configured. You
@@ -115,8 +125,9 @@ more.
 
 Run the shell command &lt;tt&gt;script/server&lt;/tt&gt; to start the server. After a short
 while, your leaf should appear in the channel you specified. You can type
-&quot;!points Coolguy +5&quot; and then &quot;!points&quot; to get started using it. Have some fun,
-and when you're satisfied, stop the server by typing &quot;!quit&quot;.
+&quot;!points Coolguy +5&quot; and then &quot;!points&quot; to get started using Scorekeeper, or
+&quot;!insult&quot; to play with Insulter. Have some fun, and when you're satisfied, stop
+the server by typing &quot;!quit&quot;.
 
 If you'd like to daemonize your server, you can use the shell commands &lt;tt&gt;rake
 app:start&lt;/tt&gt; and &lt;tt&gt;rake app:stop&lt;/tt&gt;. For more information, see &quot;Tasks&quot;
@@ -130,7 +141,8 @@ to make a simple Fortune bot that responds to a few basic commands.
 === Step 1: Subclass Leaf
 
 Create a new leaf by typing &lt;tt&gt;script/generate leaf fortune&lt;/tt&gt;. This will
-create a fortune.rb file in the leaves directory. Edit this file. First we'll
+create a fortune directory in the leaves directory, along with the bare bones of
+files needed within that directory. Edit the controller.rb file. First we'll
 create an array to hold our fortunes:
 
  FORTUNES = [
@@ -153,8 +165,8 @@ at random, which is automatically transmitted to the channel or nick where the
 command was received.
 
 Of course, any self-respecting fortune bot announces its presence when it starts
-up, so, in your +Fortune+ class, override the Autumn::Leaf#did_start_up method
-to display a cheerful greeting:
+up, so, in your +Controller+ class, override the Autumn::Leaf#did_start_up
+method to display a cheerful greeting:
 
  def did_start_up
    stems.message 'FortuneBot at your service! Type &quot;!fortune&quot; to get your fortune!'
@@ -169,7 +181,7 @@ two -- but &lt;i&gt;three&lt;/i&gt; unique and exciting fortunes!
 
 If you want, you can add the fortune bot to your leaves.yml and stems.yml files
 to try it out. Adding a leaf is easy; simply duplicate the structure used for
-Scorekeeper's entry and change the values as appropriate. A typical two-leaf
+another leaf's entry and change the values as appropriate. A typical two-leaf
 configuration will look like:
 
  Scorekeeper:
@@ -188,6 +200,9 @@ so:
  Fortune2:
    class: Fortune
 
+This doesn't make a whole lot of sense for our fortune bot, but for more
+complicated bots it can be useful.
+
 We've created the leaf, but we have to add it to the stem for it to work.
 (Remember, a stem is an IRC connection and a leaf is a bot.) So, in your
 stems.yml file, add an entry for this leaf. Your new config will appear
@@ -202,17 +217,42 @@ something like:
    channel: somechannel
    server: irc.someserver.com
 
-When you restart the server, Scorekeeper will come back online but will now
-also respond to the &quot;!fortune&quot; command. This is a helpful tutorial on how stems
-and leaves are separate. One leaf can have many stems, and one stem can have
-many leaves. You can combine these two entities however you need.
+When you restart the server, the bot will come back online and will now also
+respond to the &quot;!fortune&quot; command. This is a helpful tutorial on how stems and
+leaves are separate. One leaf can have many stems, and one stem can have many
+leaves. You can combine these two entities however you need.
+
+=== Step 3: Upgrade to ERb Views
+
+You've already learned that for your &lt;tt&gt;[word]_command&lt;/tt&gt;-type methods, the
+bot responds with whatever string your method returns. For more complicated
+commands, however, you may want to upgrade to full view abstraction, a la Ruby
+on Rails. This is what the views directory is for.
+
+If you place a .txt.erb file in the views directory named after your command, it
+will be parsed by ERb and rendered as the result. You can pass variables to the
+ERb parser by using the Autumn::Leaf#var method. Let's upgrade our
++fortune_command+ method for that:
+
+ def fortune_command(stem, sender, reply_to, msg)
+   var :fortune =&gt; FORTUNES.at_rand
+ end
+
+We can then write a view, fortune.txt.erb, which will render the fortune:
+
+ &lt;%= var :fortune %&gt;
+
+OK, so admittedly, this doesn't really get us anywhere, but for more complicated
+bots, this well help separate view and controller concerns.
+
+For more information on view rendering, see the Autumn::Leaf#render method.
 
 == Seasons
 
-Each time you start Autumn with the rake task, the process launches in a certain
-season (a.k.a. environment context). This season is defined in the
-config/global.yml file. You can temporarily override it by setting the +SEASON+
-environment variable (e.g., &lt;tt&gt;SEASON=production script/server&lt;/tt&gt;).
+Each time you start Autumn, the process launches in a certain season (a.k.a.
+environment context). This season is defined in the config/global.yml file. You
+can temporarily override it by setting the +SEASON+ environment variable (e.g.,
+&lt;tt&gt;SEASON=production script/server&lt;/tt&gt;).
 
 It's important to realize that an season is just a name, nothing more. You can
 have as many seasons as you like, and name them anything that you like. Autumn
@@ -221,10 +261,9 @@ doesn't really care if it's named &quot;production&quot; or &quot;live&quot; or
 &quot;testing-on-jeffs-machine&quot;; it's all the same to Autumn.
 
 Your season's configuration is stored in the season.yml file within your season
-directory. Currently it supports one directive, +logging+. When set to &quot;debug&quot;,
-the logger will log all messages, and will parrot output to the console. When
-set to &quot;production&quot;, the logger will not log debug messages, and will not parrot
-to the console. (See the &quot;Logging&quot; section.)
+directory. Currently it supports one directive, +logging+. This sets the minimum
+log level (such as +debug+ or +warn+). If the log level is set to +debug+, it
+also enables console output parroting. (See the &quot;Logging&quot; section.)
 
 The power of seasons comes in custom configuration options. For instance,
 consider that you have a testing and production season. In your testing season,
@@ -254,7 +293,7 @@ System-wide configuration is done in the config/global.yml file. It supports by
 default the following directives:
 
 +season+:: The season to launch in.
-+log_history+:: The number of historical logfiles to keep.
++log_history+:: The number of historical logfiles to keep (default 10).
 
 In addition, the following options are available (but cannot be set in the yml
 file):
@@ -265,8 +304,8 @@ file):
 ==== Season
 
 Season-specific configuration is done in the config/seasons/[season]/season.yml
-file. Currently it only supports one directive, +logging+. When set to +debug+,
-the logger will log all messages and parrot to stdout.
+file. Currently it only supports one directive, +logging+, which takes log
+levels such as +debug+ or +warn+.
 
 ==== Stem
 
@@ -323,8 +362,9 @@ attribute.
 ==== Leaf
 
 Leaf-specific configuration is done in the config/seasons/[season]/leaves.yml
-file. As mentioned above, leaf and stem configurations are completely separate,
-so one does not override the other. The standard options are:
+file and the leaves/[leaf]/config.yml file, with the former taking precedence
+over the latter. As mentioned above, leaf and stem configurations are completely
+separate, so one does not override the other. The standard options are:
 
 +class+:: The Autumn::Leaf subclass running this leaf. It must be a file in the
           leaves directory, named after the class (lowercase and underscored).
@@ -338,14 +378,17 @@ so one does not override the other. The standard options are:
               formatting and colorization. This defaults to mIRC-style
               formatting.
 
+The leaves.yml file is optional. When not included, each leaf in the leaves
+directory will be automatically instantiated once.
+
 === Custom Configuration Options
 
 All configuration files support user-generated directives. You can set options
 at any level. Options at a more narrow level override those at a broader level.
 
 Options are maintained and cataloged by the Autumn::Speciator singleton. You
-could access the singleton directly, but most objects have a +config+ or
-+options+ attribute providing simpler access to the Speciator.
+could access the singleton directly, but most objects have an +options+
+attribute providing simpler access to the Speciator.
 
 For example, to access options in a leaf, all you do is call, for example,
 &lt;tt&gt;options[:my_custom_option]&lt;/tt&gt;. +my_custom_option+ can be set at the
@@ -371,7 +414,7 @@ to these events.
 
 &lt;b&gt;Invoked methods&lt;/b&gt;:: +will_start_up+, +did_start_up+,
                          +did_receive_channel_message+, etc.
-&lt;b&gt;Utility methods&lt;/b&gt;:: +before_filter+, +database+
+&lt;b&gt;Utility methods&lt;/b&gt;:: +before_filter+, +database+, etc.
 &lt;b&gt;IRC commands&lt;/b&gt;:: +quit_command+, +reload_command+, +autumn_command+, etc.
 
 See the class docs for more information on these methods.
@@ -399,7 +442,7 @@ and they are added to the filter chain using the +before_filter+ and
 +after_filter+ methods (like in Ruby on Rails). As an example, imagine you
 wanted your bot to say something after each command:
 
- class OutroLeaf &gt; Autumn::Leaf
+ class Controller &gt; Autumn::Leaf
    after_filter :outro
  
    private
@@ -430,7 +473,7 @@ your filter.
 As an example, here's a simple form of authentication that just checks a
 person's nick:
 
- class MyLeaf &lt; Autumn::Leaf
+ class Controller &lt; Autumn::Leaf
    before_filter :authenticate, :only =&gt; :quit, :admin =&gt; 'Yournick'
  
    def authenticate_filter(stem, channel, sender, command, msg, opts)
@@ -458,7 +501,7 @@ in order:
 3. the sender hash,
 4. the name of the command that was typed, as a symbol,
 5. any additional parameters after the command (same as the +msg+ parameter in
-   the &lt;tt&gt;*_command&lt;/tt&gt; methods),
+   the &lt;tt&gt;[word]_command&lt;/tt&gt; methods),
 6. the custom options that were given to +before_filter+ or +after_filter+.
 
 There are two built-in options that you can specify for +before_filter+ and
@@ -515,10 +558,10 @@ Because of this, it's important to understand how to manage your connections.
 Autumn tries to do this for you by guessing which connection belongs to which
 leaf, based on their names.
 
-For example, imagine you have a leaf subclass named +Fortune+ and a
-configuration in leaves.yml named &quot;MyFortune&quot;. If you name your database
-connection either &quot;Fortune&quot; or &quot;MyFortune&quot; (or &quot;fortune&quot; or &quot;my_fortune&quot;), it
-will automatically be associated with that leaf. What this means is that for the
+For example, imagine you have a leaf named &quot;Fortune&quot; and an instance of that
+leaf in leaves.yml named &quot;MyFortune&quot;. If you name your database connection
+either &quot;Fortune&quot; or &quot;MyFortune&quot; (or &quot;fortune&quot; or &quot;my_fortune&quot;), it will
+automatically be associated with that leaf. What this means is that for the
 leaf's command methods (such as +about_command+) and invoked methods (such as
 +did_receive_private_message+), the database connection will already be set for
 you, and you can start using your DataMapper objects just like ActiveRecord
@@ -531,7 +574,7 @@ by a Stem, or a different listener), you will need to call the +database+ method
 and pass it a block containing your code.
 
 This is terribly confusing, so let me give you an example. Let's assume you've
-got a fortune bot running off of a +FortuneLeaf+ subclass, so your leaf
+got a fortune bot running a leaf named &quot;FortuneLeaf&quot;, so your leaves.yml
 configuration is:
 
  FortuneBot:
@@ -545,8 +588,10 @@ And you have a database connection for that leaf, named after the leaf's class:
 
 Let's further assume you have a simple DataMapper object:
 
- class Fortune &lt; DataMapper::Base
-   property :text, :string
+ class Fortune
+   include DataMapper::Resource
+   property :id, Integer, :serial =&gt; true
+   property :text, String
  end
 
 Now, if we wanted to write a &quot;!fortune&quot; command, it would appear something like
@@ -558,7 +603,7 @@ this:
  end
 
 Autumn automatically knows to execute this DataMapper code in the correct
-database context. It knows this because your leaf's class is +FortuneLeaf+, and
+database context. It knows this because your leaf's name is FortuneLeaf, and
 your database context is named the same.
 
 But what if you wanted to use that connection for other leaves too, so you named
@@ -596,34 +641,47 @@ directly, giving the Autumn::Leaf class no chance to set up the database first.
 So to fix it, make a call to +database+ first:
 
  def ctcp_version_request(handler, stem, sender, arguments)
-   database do
-     fortune = random_fortune # Loads a random fortune
-     send_ctcp_reply stem, sender[:nick], 'VERSION', fortune.text
-   end
+   fortune = database { random_fortune }
+   send_ctcp_reply stem, sender[:nick], 'VERSION', fortune.text
  end
 
 This will execute those methods in the scope of the database connection guessed
 by Autumn::Leaf. Of course, you can manually pass in a connection name if
 necessary.
 
+=== Your Leaf's Module; or, &quot;What Do I Do About Namespace Conflicts?&quot;
+
+So, if you have two database-backed leaves, it's entirely likely that both of
+them will use some sort of DataMapper resource named +Channel+, or something
+similar. You can't define the class +Channel+ twice in two different ways, so
+how do you deal with this?
+
+The answer is: it's already dealt with for you. Go ahead and define the class
+twice. Or three times.
+
+The longer explanation is: Secretly, behind the scenes, &lt;b&gt;all your leaf code is
+being cleverly loaded into a module named after your leaf&lt;/b&gt;. So, when, in your
+controller.rb code, it says &lt;tt&gt;class Controller &lt; Autumn::Leaf&lt;/tt&gt;, you should
+read it as &lt;tt&gt;class MyLeafName::Controller &lt; Autumn::Leaf&lt;/tt&gt;. When you define
+your model with &lt;tt&gt;class Channel&lt;/tt&gt;, it's really read as &lt;tt&gt;class
+MyLeafName::Channel&lt;/tt&gt;.
+
+Don't worry about table names or associations or anything, either. Just go ahead
+and use it as if it weren't in a module. The libs/datamapper_hacks.rb file has
+all the necessary code changes to make this bit of trickery work.
+
 === Using Support Modules
 
-Helper modules placed in the support/ directory will automatically be loaded and
-included in your leaf classes. To create a helper module, create a subdirectory
-within the support folder named after your leaf class. In there, you can place
-Ruby files that will be loaded. Name your helper modules after your leaf class,
-in the pattern of &quot;&lt;Leaf Name&gt;&lt;Helper Name&gt;Helper&quot;.
+Helper modules placed in your leaf's helpers directory will automatically be
+loaded and included in your leaf controller and views. To create a helper
+module, place Ruby files to be loaded into the helpers directory. Make sure your
+helper modules' names end with the word &quot;Helper&quot;.
 
-For instance, if your leaf class is +Fortune+, and you needed two helpers, a
+For instance, if your leaf's name is &quot;Fortune&quot;, and you needed two helpers, a
 database helper and a network helper, you could create two modules named
-+FortuneDatabaseHelper+ and +FortuneNetworkHelper+. If you only needed on
-helper, you could name the module +FortuneHelper+. These modules should be
-defined in Ruby source files within the support/fortune directory. Any modules
-named in this fashion and defined in that location will be loaded and appended
-to the +Fortune+ class automatically.
-
-If you are using DataMapper, you can also place your leaf's DataMapper objects
-in the support directory.
++DatabaseHelper+ and +NetworkHelper+. Any modules named in this fashion and
+placed in the helpers subdirectory will be loaded and appended to the
+Fortune controller and its views automatically.
 
 === Debugging Your Leaf
 
@@ -631,9 +689,8 @@ If you make a simple code change to your leaf, you can reload it without having
 to restart the whole process. See the Autumn::Leaf#reload_command documentation
 for more information on when and how you can reload your leaf's code.
 
-If an error occurs on a live production instance, it will be logged to the
-log file for your season and the leaf will exit. You can inspect the log file
-to determine what went wrong.
+If an error occurs on a live production instance, it will be logged to the log
+file for your season. You can inspect the log file to determine what went wrong.
 
 If the error happens before the logger is available, oftentimes it will appear
 in the autumn-leaves.output or autumn-leaves.log files. These files are
@@ -649,9 +706,9 @@ Unfortunately, it's still possible that the bug might not appear when you do
 this, but only appear when the process is daemonized. In this situation, I'd
 recommend installing rdebug (&lt;tt&gt;sudo gem install rdebug&lt;/tt&gt;) and stepping
 through the code to figure out what's going wrong. In particular, make sure you
-step into the Foliater's +start_stems+ method, when it creates the new threads.
-It's possible your exception will rear its head once you step into that line of
-code.
+step into the +Foliater+'s +start_stems+ method, when it creates the new
+threads. It's possible your exception will rear its head once you step into that
+line of code.
 
 == Stems
 
@@ -741,7 +798,7 @@ that Autumn::Leaf doesn't have what you need, you may have to turn to
 Autumn::Stem to get the functionality you are looking for. So let's take a look
 at how Stem works.
 
-A stem interacts with interested parties via the _listener_ protocol. Your leaf
+A stem interacts with interested parties via the listener protocol. Your leaf
 signals its interest to a stem by calling Autumn::Stem#add_listener. When a leaf
 or any other object becomes a stem's listener, that stem then invokes methods on
 the listener whenever an IRC event occurs.
@@ -875,6 +932,20 @@ Logging tasks:
 * &lt;b&gt;rake log:errors&lt;/b&gt; - Prints a list of error-level log messages for the
   current season, and uncaught exceptions in all seasons.
 
+=== Custom leaf tasks
+
+You can define your own leaf-specific tasks in the tasks subdirectory within
+your leaf's directory. Any .rake files there will be loaded by rake. The tasks
+will be added within a task-group named after your leaf. Use Scorekeeper as an
+example: If you type &lt;tt&gt;rake --tasks&lt;/tt&gt;, you'll see one other task,
+&lt;tt&gt;rake scorekeeper:scores&lt;/tt&gt;. The &quot;scores&quot; task is defined in the
+leaves/scorekeeper/tasks/stats.rake file, and placed in the &quot;scorekeeper&quot; task
+group by Autumn.
+
+Also, if you open that file up, you'll notice that you have to refer to your
+leaf's classes by their _full_ names, including the leaf module. (See &quot;Your
+Leaf's Module&quot; if you're confused.)
+
 == Scripts
 
 Autumn includes four scripts to help you control it.
@@ -917,7 +988,8 @@ Usage: script/destroy &lt;options&gt; &lt;object&gt; &lt;name&gt;
 
 &lt;tt&gt;--help, -h&lt;/tt&gt;:: Displays this usage information.
 &lt;tt&gt;--vcs, -c&lt;/tt&gt;:: Remove any created files or directories from the project's
-                     version control system. (Autodetects CVS and Subversion.)
+                     version control system. (Autodetects CVS, Git, and
+                     Subversion.)
 
 === script/generate
 
@@ -931,7 +1003,8 @@ Usage: script/generate &lt;options&gt; &lt;template&gt; &lt;name&gt;
 
 &lt;tt&gt;--help, -h&lt;/tt&gt;:: Displays this usage information.
 &lt;tt&gt;--vcs, -c&lt;/tt&gt;:: Add any created files or directories to the project's
-                     version control system. (Autodetects CVS and Subversion.)
+                     version control system. (Autodetects CVS, Git, and
+                     Subversion.)
 
 === script/server
 </diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 h1. Autumn: A Ruby IRC Bot Framework
-*Version 2.0.3 (Mar 22, 2008)*
+*Version 3.0 (Jul 4, 2008)*
 
 | Author | Tim Morgan (mailto:riscfuture@gmail.com) |
 | Copyright | Copyright (c)2007-2008 Tim Morgan |
@@ -14,15 +14,16 @@ support.
 h2. Requirements
 
 Autumn requires &quot;RubyGems&quot;:http://www.rubygems.org and the Daemons and Facets*
-gems. Install RubyGems then run
-@sudo gem install daemons ; sudo gem install facets -v '=2.3'@ in a command line
-in order to run Autumn.
+gems. Install RubyGems then run @sudo gem install daemons facets@ in a command
+line in order to run Autumn.
 
 If you wish to use a database backend for your bot, you will need the DataMapper
 gem. To install, see the &quot;DataMapper website&quot;:http://www.datamapper.org.
 
-The included example bot, Scorekeeper, requires the DataMapper gem. It can
-optionally use the Chronic gem to enhance its textual date parsing.
+The included example bot Scorekeeper requires the DataMapper gem. It can
+optionally use the Chronic gem to enhance its textual date parsing. The other
+example bot, Insulter, is much simpler and can run under any Autumn
+configuration.
 
 h2. Directory Structure
 
@@ -32,42 +33,49 @@ seem confusing to people who have never used Autumn before, but bear with me. In
 a bit I will explain in detail what all of this stuff is. For now, here is an
 overview you can consult for future reference:
 
-* *config/* - Configuration files and
+* *config/* - Configuration files and season definitions
 ** global.yml - Universal settings that apply to every season
-** *seasons/* - Contains directories for each season (see *Seasons*)
-*** *testing/* - Example season
-**** database.yml - Example database configuration file
-**** leaves.yml - Example bot configuration file
-**** season.yml - Season configuration
-**** stems.yml - Example IRC configuration file
-* *data/* - Not used by the program, but you can store your SQLite database
-  files here.
+*** *seasons/* - Contains directories for each season (see *Seasons*)
+**** *testing/* - Example season
+***** database.yml - Example database configuration file
+***** leaves.yml - Example bot configuration file
+***** season.yml - Season configuration
+***** stems.yml - Example IRC configuration file
 * *doc/* - HTML documentation generated by RDoc
 ** *api/* - Autumn API documentation
 ** *leaves/* - Autumn leaves documentation
-* *leaves/* - @Autumn::Leaf@ subclasses
-** scorekeeper.rb - Example leaf provided with the installation
+* *leaves/* - Autumn leaves. Each subdirectory contains all the code and
+  data for a leaf.
+** *insulter/* - Very simple example leaf
+*** _See the *scorekeeper* directory_
+** *scorekeeper/* - Database-backed, full-featured example leaf
+*** config.yml - Optional leaf-global configuration options
+*** controller.rb - The leaf's controller object
+*** *data/* - Optional directory for data storage (not used by Autumn)
+*** *helpers/* - Modules that extend the controller and views
+*** *models/* - Active record-type database objects
+*** *tasks/* - Additional rake tasks for this leaf (see *Custom leaf tasks*)
+*** *views/* - ERb views for each of the leaf's commands
 * *libs/* - Autumn core code
 ** channel_leaf.rb - A leaf subclass that can ignore messages from certain
    channels its in
-** coder.rb - Used by &lt;tt&gt;script/generate&lt;/tt&gt; to write out Ruby code
+** coder.rb - Used by script/generate to write out Ruby code
 ** ctcp.rb - CTCP support library
 ** daemon.rb - Provides support for different kinds of IRC servers
 ** foliater.rb - Instantiates and manages stems and leaves
 ** formatting.rb - Provides support for different kinds of IRC client text
    formatting and colorization
-** generator.rb - Library used by &lt;tt&gt;script/generate&lt;/tt&gt;
+** generator.rb - Library used by script/generate
 ** genesis.rb - Boots the Autumn environment
 ** inheritable_attributes.rb - Adds support for class-level inheritable
    attributes
 ** leaf.rb - The core bot superclass
 ** log_facade.rb - Simplifies logging for stems and leaves
 ** misc.rb - RubyCore class additions and other knick-knacks
-** script.rb - Library used by &lt;tt&gt;script/generate&lt;/tt&gt; and
-   &lt;tt&gt;script/destroy&lt;/tt&gt;
+** script.rb - Library used by script/generate and script/destroy
 ** speciator.rb - Manages global, season, stem, and leaf configurations
 ** stem.rb - IRC client library
-** stem_facade.rb - Additional methods to simplify the @Autumn::Stem@ class
+** stem_facade.rb - Additional methods to simplify the Stem class
 * *log/* - Directory where (most) Autumn logs are written (see the *Logs*
   section)
 * Rakefile - Contains the rake tasks used to control Autumn (see the *Tasks*
@@ -80,13 +88,13 @@ overview you can consult for future reference:
 ** destroy - Destroys Autumn objects
 ** generate - Creates Autumn objects
 ** server - Starts Autumn
-* *support/* - Additional code your bots need
+* *shared/* - Shared code libraries available to all leaves
 * *tmp/* - Temporary files, such as PID files
 
 h2. Configuring Autumn for Your First Launch
 
-Before you can run Autumn and try out the example leaf, Scorekeeper, you'll need
-to set up a few things. Here are the steps:
+Before you can run Autumn and try out the example leaves, you'll need to set up
+a few things. Here are the steps:
 
 h3. Configure Your Testing Season
 
@@ -97,14 +105,14 @@ season or create a new one with @script/generate season [season name]@.
 
 First, edit the &lt;tt&gt;stems.yml&lt;/tt&gt; file. This file stores information about your
 IRC connection. Edit it to connect to an IRC server of your choosing. For more
-information, see &quot;Stems&quot; below.
+information, see *Stems* below.
 
 Next, edit the &lt;tt&gt;database.yml&lt;/tt&gt; file. As mentioned previously, Scorekeeper
 requires the DataMapper gem because it uses a persistent store. By default it's
 set up to use a MySQL database, but you can use PostgreSQL or SQLite 3 if you'd
-like. If you'd prefer not to install any of these database solutions, please
-skip to *Making Your Own Leaf*, below, disable the Scorekeeper leaf, delete the
-&lt;tt&gt;database.yml&lt;/tt&gt; file, and then continue from here.
+like. If you'd prefer not to install any of these database solutions, delete the
+&lt;tt&gt;database.yml&lt;/tt&gt; file and remove the Scorekeeper leaf from the
+&lt;tt&gt;leaves.yml&lt;/tt&gt; and &lt;tt&gt;stems.yml&lt;/tt&gt; files.
 
 Lastly, view the &lt;tt&gt;leaves.yml&lt;/tt&gt; file. You shouldn't have to make any
 changes to this file, but it's a good idea to look at it to see how leaves are
@@ -115,8 +123,9 @@ h3. Starting the Server
 
 Run the shell command @script/server@ to start the server. After a short
 while, your leaf should appear in the channel you specified. You can type
-&quot;!points Coolguy +5&quot; and then &quot;!points&quot; to get started using it. Have some fun,
-and when you're satisfied, stop the server by typing &quot;!quit&quot;.
+&quot;!points Coolguy +5&quot; and then &quot;!points&quot; to get started using Scorekeeper, or
+&quot;!insult&quot; to play with Insulter. Have some fun, and when you're satisfied, stop
+the server by typing &quot;!quit&quot;.
 
 If you'd like to daemonize your server, you can use the shell commands
 @rake app:start@ and @rake app:stop@. For more information, see *Tasks* below.
@@ -129,8 +138,9 @@ to make a simple Fortune bot that responds to a few basic commands.
 h3. Step 1: Subclass Leaf
 
 Create a new leaf by typing @script/generate leaf fortune@. This will create a
-&lt;tt&gt;fortune.rb&lt;/tt&gt; file in the &lt;tt&gt;leaves&lt;/tt&gt; directory. Edit this file. First
-we'll create an array to hold our fortunes:
+&lt;tt&gt;fortune&lt;/tt&gt; directory in the &lt;tt&gt;leaves&lt;/tt&gt; directory, along with the bare
+bones of files needed within that directory. Edit the &lt;tt&gt;controller.rb&lt;/tt&gt;
+file. First we'll create an array to hold our fortunes:
 
 &lt;pre&gt;&lt;code&gt;
 FORTUNES = [
@@ -150,12 +160,13 @@ def fortune_command(stem, sender, reply_to, msg)
 end
 &lt;/code&gt;&lt;/pre&gt;
 
-The @at_rand@ method is provided by Facets. Our method returns a fortune at
+The @at_rand@ method is provided by Facets, so you'll need to add a @require
+'facets/random'@ line at the top of your file. Our method returns a fortune at
 random, which is automatically transmitted to the channel or nick where the
 command was received.
 
 Of course, any self-respecting fortune bot announces its presence when it starts
-up, so, in your @Fortune@ class, override the @Autumn::Leaf#did_start_up@ method
+up, so, in your @Controller@ class, override the @Autumn::Leaf#did_start_up@ method
 to display a cheerful greeting:
 
 &lt;pre&gt;&lt;code&gt;
@@ -173,8 +184,8 @@ h3. Step 2: Add the Leaf to Your Season
 
 If you want, you can add the fortune bot to your &lt;tt&gt;leaves.yml&lt;/tt&gt; and
 &lt;tt&gt;stems.yml&lt;/tt&gt; files to try it out. Adding a leaf is easy; simply duplicate
-the structure used for Scorekeeper's entry and change the values as appropriate.
-A typical two-leaf configuration will look like:
+the structure used for another leaf's entry and change the values as
+appropriate. A typical two-leaf configuration will look like:
 
 &lt;pre&gt;&lt;code&gt;
 Scorekeeper:
@@ -196,6 +207,9 @@ Fortune2:
   class: Fortune
 &lt;/code&gt;&lt;/pre&gt;
 
+This doesn't make a whole lot of sense for our fortune bot, but for more
+complicated bots it can be useful.
+
 We've created the leaf, but we have to add it to the stem for it to work.
 (Remember, a stem is an IRC connection and a leaf is a bot.) So, in your
 &lt;tt&gt;stems.yml&lt;/tt&gt; file, add an entry for this leaf. Your new config will appear
@@ -206,23 +220,52 @@ Example:
   nick: Scorekeeper
   leaves:
     - Scorekeeper
+    - Insulter
     - Fortune
   rejoin: true
   channel: somechannel
   server: irc.someserver.com
 &lt;/code&gt;&lt;/pre&gt;
 
-When you restart the server, Scorekeeper will come back online but will now
-also respond to the &quot;!fortune&quot; command. This is a helpful tutorial on how stems
-and leaves are separate. One leaf can have many stems, and one stem can have
-many leaves. You can combine these two entities however you need.
+When you restart the server, the bot will come back online and will now also
+respond to the &quot;!fortune&quot; command. This is a helpful tutorial on how stems and
+leaves are separate. One leaf can have many stems, and one stem can have many
+leaves. You can combine these two entities however you need.
+
+h3. Step 3: Upgrade to ERb Views
+
+You've already learned that for your @[word]_command@-type methods, the bot
+responds with whatever string your method returns. For more complicated
+commands, however, you may want to upgrade to full view abstraction, a la Ruby
+on Rails. This is what the &lt;tt&gt;views&lt;/tt&gt; directory is for.
+
+If you place a &lt;tt&gt;.txt.erb&lt;/tt&gt; file in the &lt;tt&gt;views&lt;/tt&gt; directory named
+after your command, it will be parsed by ERb and rendered as the result. You can
+pass variables to the ERb parser by using the @Autumn::Leaf#var@ method. Let's
+upgrade our @fortune_command@ method for that:
+
+&lt;pre&gt;&lt;code&gt;
+def fortune_command(stem, sender, reply_to, msg)
+  var :fortune =&gt; FORTUNES.at_rand
+end
+&lt;/code&gt;&lt;/pre&gt;
+
+We can then write a view, &lt;tt&gt;fortune.txt.erb&lt;/tt&gt;, which will render the
+fortune:
+
+&lt;code&gt;&lt;%= var :fortune %&gt;&lt;/code&gt;
+
+OK, so admittedly, this doesn't really get us anywhere, but for more complicated
+bots, this well help separate view and controller concerns.
+
+For more information on view rendering, see the @Autumn::Leaf#render@ method.
 
 h2. Seasons
 
-Each time you start Autumn with the rake task, the process launches in a certain
-season (a.k.a. environment context). This season is defined in the
-&lt;tt&gt;config/global.yml&lt;/tt&gt; file. You can temporarily override it by setting the
-@SEASON@ environment variable (e.g., @SEASON=production script/server@).
+Each time you start Autumn, the process launches in a certain season (a.k.a.
+environment context). This season is defined in the &lt;tt&gt;config/global.yml&lt;/tt&gt;
+file. You can temporarily override it by setting the @SEASON@ environment
+variable (e.g., @SEASON=production script/server@).
 
 It's important to realize that an season is just a name, nothing more. You can
 have as many seasons as you like, and name them anything that you like. Autumn
@@ -231,10 +274,9 @@ doesn't really care if it's named &quot;production&quot; or &quot;live&quot; or
 &quot;testing-on-jeffs-machine&quot;; it's all the same to Autumn.
 
 Your season's configuration is stored in the &lt;tt&gt;season.yml&lt;/tt&gt; file within
-your season directory. Currently it supports one directive, @logging@. When set
-to &quot;debug&quot;, the logger will log all messages, and will parrot output to the
-console. When set to &quot;production&quot;, the logger will not log debug messages, and
-will not parrot to the console. (See the *Logging* section.)
+your season directory. Currently it supports one directive, @logging@. This sets
+the minimum log level (such as @debug@ or @warn@). If the log level is set to
+@debug@, it also enables console output parroting. (See the *Logging* section.)
 
 The power of seasons comes in custom configuration options. For instance,
 consider that you have a testing and production season. In your testing season,
@@ -266,7 +308,7 @@ System-wide configuration is done in the &lt;tt&gt;config/global.yml&lt;/tt&gt; file. It
 supports by default the following directives:
 
 | @season@ | The season to launch in. |
-| @log_history@ | The number of historical logfiles to keep. |
+| @log_history@ | The number of historical logfiles to keep (default 10). |
 
 In addition, the following options are available (but cannot be set in the yml
 file):
@@ -278,8 +320,7 @@ h4. Season
 
 Season-specific configuration is done in the
 &lt;tt&gt;config/seasons/[season]/season.yml&lt;/tt&gt; file. Currently it only supports one
-directive, @logging@. When set to @debug@, the logger will log all messages and
-parrot to @STDOUT@.
+directive, @logging@, which takes log levels like @debug@ or @warn@.
 
 h4. Stem
 
@@ -334,9 +375,10 @@ attribute.
 h4. Leaf
 
 Leaf-specific configuration is done in the
-&lt;tt&gt;config/seasons/[season]/leaves.yml&lt;/tt&gt; file. As mentioned above, leaf and
-stem configurations are completely separate, so one does not override the other.
-The standard options are:
+&lt;tt&gt;config/seasons/[season]/leaves.yml&lt;/tt&gt; file and the
+&lt;tt&gt;leaves/[leaf]/config.yml&lt;/tt&gt; file, with the former taking precedence over
+the latter. As mentioned above, leaf and stem configurations are completely
+separate, so one does not override the other. The standard options are:
 
 | @class@ | The @Autumn::Leaf@ subclass running this leaf. It must be a file in the &lt;tt&gt;leaves&lt;/tt&gt; directory, named after the class (lowercase and underscored). |
 | @command_prefix@ | The text that must precede each command. Defaults to &quot;!&quot;. |
@@ -344,14 +386,17 @@ The standard options are:
 | @database@ | A database connection to use (as defined in &lt;tt&gt;database.yml&lt;/tt&gt;). By default Autumn will choose a connection named after your leaf. |
 | @formatter@ | The name of a module in @Autumn::Formatting@ that will handle output formatting and colorization. This defaults to mIRC-style formatting. |
 
+The &lt;tt&gt;leaves.yml&lt;/tt&gt; file is optional. When not included, each leaf in the
+&lt;tt&gt;leaves&lt;/tt&gt; directory will be automatically instantiated once.
+
 h3. Custom Configuration Options
 
 All configuration files support user-generated directives. You can set options
 at any level. Options at a more narrow level override those at a broader level.
 
 Options are maintained and cataloged by the @Autumn::Speciator@ singleton. You
-could access the singleton directly, but most objects have a @config@ or
-@options@ attribute providing simpler access to the Speciator.
+could access the singleton directly, but most objects have an @options@
+attribute providing simpler access to the Speciator.
 
 For example, to access options in a leaf, all you do is call, for example,
 @options[:my_custom_option]@. @my_custom_option@ can be set at the
@@ -376,7 +421,7 @@ message is received. You override them in your leaf to customize how it responds
 to these events.
 
 | *Invoked methods* | @will_start_up@, @did_start_up@, @did_receive_channel_message@, etc. |
-| *Utility methods* | @before_filter@, @database@ |
+| *Utility methods* | @before_filter@, @database@, etc. |
 | *IRC commands* | @quit_command@, @reload_command@, @autumn_command@, etc. |
 
 See the class docs for more information on these methods.
@@ -405,7 +450,7 @@ methods (like in Ruby on Rails). As an example, imagine you wanted your bot to
 say something after each command:
 
 &lt;pre&gt;&lt;code&gt;
-class OutroLeaf &gt; Autumn::Leaf
+class Controller &gt; Autumn::Leaf
   after_filter :outro
 
   private
@@ -437,7 +482,7 @@ As an example, here's a simple form of authentication that just checks a
 person's nick:
 
 &lt;pre&gt;&lt;code&gt;
-class MyLeaf &lt; Autumn::Leaf
+class Controller &lt; Autumn::Leaf
   before_filter :authenticate, :only =&gt; :quit, :admin =&gt; 'Yournick'
 
   def authenticate_filter(stem, channel, sender, command, msg, opts)
@@ -525,14 +570,14 @@ Because of this, it's important to understand how to manage your connections.
 Autumn tries to do this for you by guessing which connection belongs to which
 leaf, based on their names.
 
-For example, imagine you have a leaf subclass named @Fortune@ and a
-configuration in &lt;tt&gt;leaves.yml&lt;/tt&gt; named &quot;MyFortune&quot;. If you name your
-database connection either &quot;Fortune&quot; or &quot;MyFortune&quot; (or &quot;fortune&quot; or
-&quot;my_fortune&quot;), it will automatically be associated with that leaf. What this
-means is that for the leaf's command methods (such as @about_command@) and
-invoked methods (such as @did_receive_private_message@), the database connection
-will already be set for you, and you can start using your DataMapper objects
-just like ActiveRecord objects.
+For example, imagine you have a leaf named &quot;Fortune&quot; and an instance of that
+leaf in &lt;tt&gt;leaves.yml&lt;/tt&gt; named &quot;MyFortune&quot;. If you name your database
+connection either &quot;Fortune&quot; or &quot;MyFortune&quot; (or &quot;fortune&quot; or &quot;my_fortune&quot;), it
+will automatically be associated with that leaf. What this means is that for the
+leaf's command methods (such as @about_command@) and invoked methods (such as
+@did_receive_private_message@), the database connection will already be set for
+you, and you can start using your DataMapper objects just like ActiveRecord
+objects.
 
 If, on the other hand, you either *named your database connection differently
 from your leaf or subclass name* or you are *writing a method outside of the
@@ -541,8 +586,8 @@ normal flow of leaf methods* (for instance, one that is directly called by a
 and pass it a block containing your code.
 
 This is terribly confusing, so let me give you an example. Let's assume you've
-got a fortune bot running off of a @FortuneLeaf@ subclass, so your leaf
-configuration is:
+got a fortune bot running a leaf named &quot;FortuneLeaf&quot;, so your
+&lt;tt&gt;leaves.yml&lt;/tt&gt; configuration is:
 
 &lt;pre&gt;&lt;code&gt;
 FortuneBot:
@@ -560,8 +605,10 @@ fortune_leaf:
 Let's further assume you have a simple DataMapper object:
 
 &lt;pre&gt;&lt;code&gt;
-class Fortune &lt; DataMapper::Base
-  property :text, :string
+class Fortune
+  include DataMapper::Resource
+  property :id, Integer, :serial =&gt; true
+  property :text, String
 end
 &lt;/code&gt;&lt;/pre&gt;
 
@@ -576,7 +623,7 @@ end
 &lt;/code&gt;&lt;/pre&gt;
 
 Autumn automatically knows to execute this DataMapper code in the correct
-database context. It knows this because your leaf's class is @FortuneLeaf@, and
+database context. It knows this because your leaf's name is FortuneLeaf, and
 your database context is named the same.
 
 But what if you wanted to use that connection for other leaves too, so you named
@@ -621,10 +668,8 @@ first. So to fix it, make a call to @database@ first:
 
 &lt;pre&gt;&lt;code&gt;
 def ctcp_version_request(handler, stem, sender, arguments)
-  database do
-    fortune = random_fortune # Loads a random fortune
-    send_ctcp_reply stem, sender[:nick], 'VERSION', fortune.text
-  end
+  fortune = database { random_fortune }
+  send_ctcp_reply stem, sender[:nick], 'VERSION', fortune.text
 end
 &lt;/code&gt;&lt;/pre&gt;
 
@@ -632,24 +677,39 @@ This will execute those methods in the scope of the database connection guessed
 by @Autumn::Leaf@. Of course, you can manually pass in a connection name if
 necessary.
 
+h3. Your Leaf's Module; or, &quot;What Do I Do About Namespace Conflicts?&quot;
+
+So, if you have two database-backed leaves, it's entirely likely that both of
+them will use some sort of DataMapper resource named @Channel@, or something
+similar. You can't define the class @Channel@ twice in two different ways, so
+how do you deal with this?
+
+The answer is: it's already dealt with for you. Go ahead and define the class
+twice. Or three times.
+
+The longer explanation is: Secretly, behind the scenes, *all your leaf code is
+being cleverly loaded into a module named after your leaf*. So, when, in your
+&lt;tt&gt;controller.rb&lt;/tt&gt; code, it says @class Controller &lt; Autumn::Leaf@, you
+should read it as @class MyLeafName::Controller &lt; Autumn::Leaf@. When you define
+your model with @class Channel@, it's really read as @class
+MyLeafName::Channel@.
+
+Don't worry about table names or associations or anything, either. Just go ahead
+and use it as if it weren't in a module. The &lt;tt&gt;libs/datamapper_hacks.rb&lt;/tt&gt;
+file has all the necessary code changes to make this bit of trickery work.
+
 h3. Using Support Modules
 
-Helper modules placed in the &lt;tt&gt;support&lt;/tt&gt; directory will automatically be
-loaded and included in your leaf classes. To create a helper module, create a
-subdirectory within the &lt;tt&gt;support&lt;/tt&gt; folder named after your leaf class. In
-there, you can place Ruby files that will be loaded. Name your helper modules
-after your leaf class, in the pattern of &quot;{Leaf Name}{Helper Name}Helper&quot;.
+Helper modules placed in your leaf's &lt;tt&gt;helpers&lt;/tt&gt; directory will
+automatically be loaded and included in your leaf controller and views. To
+create a helper module, place Ruby files to be loaded into the &lt;tt&gt;helpers&lt;/tt&gt;
+directory. Make sure your helper modules' names end with the word &quot;Helper&quot;.
 
-For instance, if your leaf class is @Fortune@, and you needed two helpers, a
+For instance, if your leaf's name is &quot;Fortune&quot;, and you needed two helpers, a
 database helper and a network helper, you could create two modules named
-@FortuneDatabaseHelper@ and @FortuneNetworkHelper@. If you only needed on
-helper, you could name the module @FortuneHelper@. These modules should be
-defined in Ruby source files within the &lt;tt&gt;support/fortune&lt;/tt&gt; directory. Any
-modules named in this fashion and defined in that location will be loaded and
-appended to the @Fortune@ class automatically.
-
-If you are using DataMapper, you can also place your leaf's DataMapper objects
-in the support directory.
+@DatabaseHelper@ and @NetworkHelper@. Any modules named in this fashion and
+placed in the &lt;tt&gt;helpers&lt;/tt&gt; subdirectory will be loaded and appended to the
+Fortune controller and its views automatically.
 
 h3. Debugging Your Leaf
 
@@ -658,9 +718,8 @@ to restart the whole process. See the @Autumn::Leaf#reload_command@
 documentation for more information on when and how you can reload your leaf's
 code.
 
-If an error occurs on a live production instance, it will be logged to the
-log file for your season and the leaf will exit. You can inspect the log file
-to determine what went wrong.
+If an error occurs on a live production instance, it will be logged to the log
+file for your season. You can inspect the log file to determine what went wrong.
 
 If the error happens before the logger is available, oftentimes it will appear
 in the &lt;tt&gt;autumn-leaves.output&lt;/tt&gt; or &lt;tt&gt;autumn-leaves.log&lt;/tt&gt; files. These
@@ -676,7 +735,7 @@ Unfortunately, it's still possible that the bug might not appear when you do
 this, but only appear when the process is daemonized. In this situation, I'd
 recommend installing rdebug (@sudo gem install rdebug@) and stepping through the
 code to figure out what's going wrong. In particular, make sure you step into
-the Foliater's @start_stems@ method, when it creates the new threads. It's
+the @Foliater@'s @start_stems@ method, when it creates the new threads. It's
 possible your exception will rear its head once you step into that line of code.
 
 h2. Stems
@@ -775,7 +834,7 @@ need to deal with a stem directly? Generally, never. However, if you find that
 @Autumn::Stem@ to get the functionality you are looking for. So let's take a
 look at how Stem works.
 
-A stem interacts with interested parties via the _listener_ protocol. Your leaf
+A stem interacts with interested parties via the listener protocol. Your leaf
 signals its interest to a stem by calling @Autumn::Stem#add_listener@. When a
 leaf or any other object becomes a stem's listener, that stem then invokes
 methods on the listener whenever an IRC event occurs.
@@ -913,6 +972,20 @@ Logging tasks:
 | @rake log:clear@ | Clears the log files for all seasons. |
 | @rake log:errors@ | Prints a list of error-level log messages for the current season, and uncaught exceptions in all seasons. |
 
+h3. Custom leaf tasks
+
+You can define your own leaf-specific tasks in the &lt;tt&gt;tasks&lt;/tt&gt; subdirectory
+within your leaf's directory. Any &lt;tt&gt;.rake&lt;/tt&gt; files there will be loaded by
+rake. The tasks will be added within a task-group named after your leaf. Use
+Scorekeeper as an example: If you type @rake --tasks@, you'll see one other
+task, @rake scorekeeper:scores@. The &quot;scores&quot; task is defined in the
+&lt;tt&gt;leaves/scorekeeper/tasks/stats.rake&lt;/tt&gt; file, and placed in the
+&quot;scorekeeper&quot; task group by Autumn.
+
+Also, if you open that file up, you'll notice that you have to refer to your
+leaf's classes by their _full_ names, including the leaf module. (See *Your
+Leaf's Module* if you're confused.)
+
 h2. Scripts
 
 Autumn includes four scripts to help you control it.
@@ -953,7 +1026,7 @@ Usage: @script/destroy [options] [object] [name]@
 | [name] | The name of the object to destroy. For example, you can call @script/destroy leaf Scorekeeper@ to remove a leaf named Scorekeeper. |
 
 | @--help, -h@ | Displays this usage information. |
-| @--vcs, -c@ | Remove any created files or directories from the project's version control system. (Autodetects CVS and Subversion.) |
+| @--vcs, -c@ | Remove any created files or directories from the project's version control system. (Autodetects CVS, Git, and Subversion.) |
 
 h3. &lt;tt&gt;script/generate&lt;/tt&gt;
 
@@ -965,7 +1038,7 @@ Usage: @script/generate [options] [template] [name]@
 | [name] | The name to give the created template. For example, you can call @script/generate leaf Scorekeeper@ to create a leaf named Scorekeeper. |
 
 | @--help, -h@ | Displays this usage information. |
-| @--vcs, -c@ | Add any created files or directories to the project's version control system. (Autodetects CVS and Subversion.) |
+| @--vcs, -c@ | Add any created files or directories to the project's version control system. (Autodetects CVS, Git, and Subversion.) |
 
 h3. &lt;tt&gt;script/server&lt;/tt&gt;
 </diff>
      <filename>README.textile</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,10 @@
+# This file is optional: If Autumn doesn't find it, Autumn will assume you want
+# one instance of every leaf in the leaves directory, named after the leaf
+# itself. You only need this file if you want more than one instance of a leaf
+# or you need to configure your leaf differently.
+
 --- 
 Scorekeeper: 
   class: Scorekeeper
+Insulter:
+  class: Insulter</diff>
      <filename>config/seasons/testing/leaves.yml</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,7 @@ Example:
   nick: Yournick
   leaves: 
   - Scorekeeper
+  - Insulter
   rejoin: true
   channel: &quot;#yourchannel&quot;
   server: irc.yourircserver.com</diff>
      <filename>config/seasons/testing/stems.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-Scorekeeper version 2.5 (3-25-08) by Tim Morgan: An Autumn Leaf.
+Scorekeeper version 3.0 (7-4-08) by Tim Morgan: An Autumn Leaf.</diff>
      <filename>leaves/scorekeeper/views/about.txt.erb</filename>
    </modified>
    <modified>
      <diff>@@ -136,7 +136,7 @@ module Autumn
   
     def ctcp_version_request(handler, stem, sender, arguments)
       return unless handler == self
-      send_ctcp_reply stem, sender[:nick], 'VERSION', &quot;Autumn 2.0.3, a Ruby IRC framework&quot;, `uname -sr`, &quot;http://autumn-leaves.googlecode.com/&quot;
+      send_ctcp_reply stem, sender[:nick], 'VERSION', &quot;Autumn 3.0, a Ruby IRC framework&quot;, `uname -sr`, &quot;http://github.com/RISCfuture/autumn&quot;
     end
   
     # Replies to a CTCP PING request by sending back the same arguments as a</diff>
      <filename>libs/ctcp.rb</filename>
    </modified>
    <modified>
      <diff>@@ -46,6 +46,9 @@ module Autumn
   # from responding to !quit. You can also protect that method using filters
   # (see &quot;Filters&quot;).
   #
+  # If you want to separate view logic from the controller, you can use ERb to
+  # template your views. See the render method for more information.
+  #
   # = Hook Methods
   #
   # Aside from adding your own &lt;tt&gt;*_command&lt;/tt&gt;-type methods, you should
@@ -89,8 +92,8 @@ module Autumn
   #
   # = Logging
   #
-  # Finally, Autumn comes with a framework for logging as well. It's very
-  # similar to the Ruby on Rails logging framework. To log an error message:
+  # Autumn comes with a framework for logging as well. It's very similar to the
+  # Ruby on Rails logging framework. To log an error message:
   #
   #  logger.error &quot;Quiz data is missing!&quot;
   #
@@ -492,7 +495,7 @@ module Autumn
     #
     # 1. If you make any change to a constant or other unchangeable value, you
     #    will need to restart the process.
-    # 2. DataMapper::Base subclasses cannot be reloaded. You will need to
+    # 2. DataMapper::Resource classes cannot be reloaded. You will need to
     #    restart the process.
     #
     # This command does not reload the YAML configuration files, only the source
@@ -513,10 +516,24 @@ module Autumn
     # that is running this leaf.
     
     def autumn_command(stem, sender, reply_to, msg)
-      &quot;Autumn version 2.0.3 (3-22-08), an IRC bot framework for Ruby (http://autumn-leaves.googlecode.com).&quot;
+      &quot;Autumn version 3.0 (7-4-08), an IRC bot framework for Ruby (http://github.com/RISCfuture/autumn).&quot;
     end
     
-    # Sets a custom view name to render. Example:
+    # Sets a custom view name to render. The name doesn't have to correspond to
+    # an actual command, just an existing view file. Example:
+    #
+    #  def my_command(stem, sender, reply_to, msg)
+    #    render :help and return if msg.empty? # user doesn't know how to use the command
+    #    [...]
+    #  end
+    #
+    # Only one view is rendered per command. If this method is called multiple
+    # times, the last value set is used. This method has no effect outside of
+    # a &lt;tt&gt;*_command&lt;/tt&gt; method.
+    #
+    # By default, the view named after the command will be rendered. If no such
+    # view exists, the value returned by the method will be used as the
+    # response.
     
     def render(view)
       # Since only one command is executed per thread, we can store the view to
@@ -536,7 +553,7 @@ module Autumn
     #
     # And in your my.txt.erb file:
     #
-    #  THERE ARE &lt;%= view_get :num_lights %&gt; LIGHTS!
+    #  THERE ARE &lt;%= var :num_lights %&gt; LIGHTS!
     
     def var(vars)
       return Thread.current[:vars][vars] if vars.kind_of? Symbol</diff>
      <filename>libs/leaf.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>51d14ebc68d5289132454f945cc2a97a75743fac</id>
    </parent>
  </parents>
  <author>
    <name>Tim Morgan</name>
    <email>riscfuture@gmail.com</email>
  </author>
  <url>http://github.com/RISCfuture/autumn/commit/f185a31b526d285ea19a7622041737dbf691ac2c</url>
  <id>f185a31b526d285ea19a7622041737dbf691ac2c</id>
  <committed-date>2008-07-04T03:40:08-07:00</committed-date>
  <authored-date>2008-07-04T03:40:08-07:00</authored-date>
  <message>Doc updates for Autumn 3.0</message>
  <tree>a1d8d41dcb1a9d0fcdfc733bb0f221c69f10feae</tree>
  <committer>
    <name>Tim Morgan</name>
    <email>riscfuture@gmail.com</email>
  </committer>
</commit>
