diff --git a/examples/thirst.rs b/examples/thirst.rs
index 914003e4d2e7d20c030e1e49667e344ec44e27f2..b0e54154831609946dd99b99a3b644bfe6f50ab5 100644
--- a/examples/thirst.rs
+++ b/examples/thirst.rs
@@ -24,7 +24,6 @@ pub fn thirst_system(time: Res<Time>, mut thirsts: Query<&mut Thirst>) {
         if thirst.thirst >= 100.0 {
             thirst.thirst = 100.0;
         }
-        println!("Thirst: {}", thirst.thirst);
     }
 }
 
@@ -105,6 +104,7 @@ pub fn thirsty_scorer_system(
             //
             // The score here must be between 0.0 and 100.0.
             score.set(thirst.thirst);
+            println!("Thirst: {}", thirst.thirst);
         }
     }
 }
diff --git a/src/evaluators.rs b/src/evaluators.rs
index 36511926027c8c5fcd23869640c37236d02d5e1c..34711ce41dabce316e1f8a846cfc8c39fcfea225 100644
--- a/src/evaluators.rs
+++ b/src/evaluators.rs
@@ -140,7 +140,7 @@ impl Default for SigmoidEvaluator {
     }
 }
 
-fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
+pub(crate) fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
     let val = if val > max { max } else { val };
     if val < min {
         min
diff --git a/src/lib.rs b/src/lib.rs
index a6f21184eea27e63a0625d430d3fb5f0c297d3b3..ddb48e8dc3bcfbb0ef37b629277eb4e0ffbcc0d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,5 +23,8 @@ pub struct BigBrainPlugin;
 impl Plugin for BigBrainPlugin {
     fn build(&self, app: &mut AppBuilder) {
         app.add_system(thinker_system.system());
+        app.add_system(fixed_score_system.system());
+        app.add_system(all_or_nothing_system.system());
+        app.add_system(sum_of_scorers_system.system());
     }
 }
diff --git a/src/scorers.rs b/src/scorers.rs
index 1343bdd1c4dfb05c29314424c649334cda2bad8b..0df09596b6cd976ceed21fec704c19b337a029af 100644
--- a/src/scorers.rs
+++ b/src/scorers.rs
@@ -6,6 +6,9 @@ use crate::ScorerEnt;
 pub struct Score(pub(crate) f32);
 
 impl Score {
+    pub fn get(&self) -> f32 {
+        self.0
+    }
     pub fn set(&mut self, value: f32) {
         if !(0.0..=100.0).contains(&value) {
             panic!("Score value must be between 0.0 and 100.0");
@@ -21,3 +24,155 @@ This trait defines new Scorers. In general, you should use the [derive macro](de
 pub trait Scorer: std::fmt::Debug + Sync + Send {
     fn build(&self, entity: Entity, cmd: &mut Commands) -> ScorerEnt;
 }
+
+#[derive(Debug)]
+pub struct FixedScore(f32);
+
+pub fn fixed_score_system(mut query: Query<(&FixedScore, &mut Score)>) {
+    for (FixedScore(fixed), mut score) in query.iter_mut() {
+        score.set(*fixed);
+    }
+}
+
+mod fixed_score {
+    use super::*;
+
+    use serde::Deserialize;
+
+    #[derive(Debug, Deserialize)]
+    struct FixedScore(f32);
+
+    #[typetag::deserialize]
+    impl Scorer for FixedScore {
+        fn build(&self, actor: Entity, cmd: &mut Commands) -> ScorerEnt {
+            let ent = ScorerEnt(cmd.spawn().id());
+            cmd.entity(ent.0)
+                .insert(Score::default())
+                .insert(super::FixedScore(self.0));
+            cmd.entity(actor).push_children(&[ent.0]);
+            ent
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct AllOrNothing {
+    threshold: f32,
+    scorers: Vec<ScorerEnt>,
+}
+
+pub fn all_or_nothing_system(query: Query<(Entity, &AllOrNothing)>, mut scores: Query<&mut Score>) {
+    for (
+        aon_ent,
+        AllOrNothing {
+            threshold,
+            scorers: children,
+        },
+    ) in query.iter()
+    {
+        let mut sum = 0.0;
+        for ScorerEnt(child) in children.iter() {
+            let score = scores.get_mut(*child).expect("where is it?");
+            if score.0 < *threshold {
+                sum = 0.0;
+                break;
+            } else {
+                sum += score.0;
+            }
+        }
+        let mut score = scores.get_mut(aon_ent).expect("where did it go?");
+        score.set(crate::evaluators::clamp(sum, 0.0, 100.0));
+    }
+}
+
+mod all_or_nothing {
+    use super::*;
+
+    use serde::Deserialize;
+
+    #[derive(Debug, Deserialize)]
+    struct AllOrNothing {
+        threshold: f32,
+        scorers: Vec<Box<dyn Scorer>>,
+    }
+
+    #[typetag::deserialize]
+    impl Scorer for AllOrNothing {
+        fn build(&self, actor: Entity, cmd: &mut Commands) -> ScorerEnt {
+            let ent = ScorerEnt(cmd.spawn().id());
+            let scorers: Vec<_> = self
+                .scorers
+                .iter()
+                .map(|scorer| scorer.build(actor, cmd).0)
+                .collect();
+            cmd.entity(ent.0)
+                .insert(Score::default())
+                .insert(super::AllOrNothing {
+                    threshold: self.threshold,
+                    scorers: scorers.into_iter().map(ScorerEnt).collect(),
+                });
+            cmd.entity(actor).push_children(&[ent.0]);
+            ent
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct SumOfScorers {
+    threshold: f32,
+    scorers: Vec<ScorerEnt>,
+}
+
+pub fn sum_of_scorers_system(query: Query<(Entity, &SumOfScorers)>, mut scores: Query<&mut Score>) {
+    for (
+        sos_ent,
+        SumOfScorers {
+            threshold,
+            scorers: children,
+        },
+    ) in query.iter()
+    {
+        let mut sum = 0.0;
+        for ScorerEnt(child) in children.iter() {
+            let score = scores.get_mut(*child).expect("where is it?");
+            sum += score.0;
+        }
+        if sum < *threshold {
+            sum = 0.0;
+        }
+        let mut score = scores.get_mut(sos_ent).expect("where did it go?");
+        score.set(crate::evaluators::clamp(sum, 0.0, 100.0));
+    }
+}
+
+mod sum_of_scorers {
+    use super::*;
+
+    use serde::Deserialize;
+
+    #[derive(Debug, Deserialize)]
+    struct SumOfScorers {
+        threshold: f32,
+        scorers: Vec<Box<dyn Scorer>>,
+    }
+
+    #[typetag::deserialize]
+    impl Scorer for SumOfScorers {
+        fn build(&self, actor: Entity, cmd: &mut Commands) -> ScorerEnt {
+            let ent = ScorerEnt(cmd.spawn().id());
+            let scorers: Vec<_> = self
+                .scorers
+                .iter()
+                .map(|scorer| scorer.build(actor, cmd).0)
+                .collect();
+            cmd.entity(ent.0)
+                .insert(Score::default())
+                .insert(super::AllOrNothing {
+                    threshold: self.threshold,
+                    scorers: scorers.into_iter().map(ScorerEnt).collect(),
+                });
+            cmd.entity(actor).push_children(&[ent.0]);
+            ent
+        }
+    }
+}