A small Ludo/Mensch ärgere Dich nicht/Pachisie game, originally developed by Richard Suchenwirth in plain Tcl (see http://wiki.tcl.tk/956). The game was rewritten as a design study in NX by Gustaf Neumann in July 2013.

Implementation

package require Tk
package require nx::trait

Class Figure

    nx::mongo::Class create Supply {
        :property by_person:required
    }
    nx::mongo::Class create SupplyGood -superclass Supply {
        :property amount:required
    }
    nx::mongo::Class create SupplyWork -superclass Supply {
        :property from:required
        :property to:required
    }

    nx::mongo::Class create Comment {
        :property author:required
        :property comment:required
    }

    nx::mongo::Class create Demand {
        :property name:required
        :property -incremental {comments:embedded,type=::evp::Comment,0..n ""}
    }
    nx::mongo::Class create DemandGood -superclass Demand {
        :property amount:double,required
        :property supplied:double
        :property -incremental {supplies:embedded,type=::evp::SupplyGood,0..n ""}
    }
    nx::mongo::Class create DemandWork -superclass Demand {
        :property from:required
        :property to:required
        :property -incremental {supplies:embedded,type=::evp::SupplyWork,0..n ""}
    }

    nx::mongo::Class create Event {
        :index tags
        :property title:required
        :property date:required
        :property ts:required
        :property {open:required 1}
        :property -incremental demands:embedded,type=::evp::Demand,0..n
        :property -incremental {tags:0..n ""}
        :property -incremental {groups:0..n ""}
    }

    nx::mongo::Class create User {
        :property name:required
        :property email:required
        :property {password ""}
        :property {name_child ""}
        :property -incremental {groups:0..n ""}
        :index groups
        :index email
    }



    Comment template set -name edit {
        Comment by <b>@:author@</b>: <em>@:comment@</em>
    }

    DemandWork template set -name edit [subst {
        <if method-true=':fulfilled'><span class="glyphicon glyphicon-check"></span></if>
        <if method-false=':fulfilled'>
          <if method-true=':event_open'>
          [add-modal supply-work -context "@:name@" -glyphicon unchecked -title "Supply Work @:name@ from @:from@ - @:to@"]
          </if>
          <if method-false=':event_open'><span class="glyphicon glyphicon-unchecked"></span></if>
        </if>
        <b>@:name@</b> <div class="pull-right"><span class="glyphicon glyphicon-time"></span> @:from@ - @:to@</div>
        [add-modal comment -glyphicon comment -context @:name@]
        <ul><FOREACH var='s' in=':supplies' type='list'>
        <if method-true="%s% show_to_user %::user%"><li>provided by: @s;obj@</li></if>
        </FOREACH></ul>
        <ul><FOREACH var='c' in=':comments' type='list'><li>@c;obj@</li></FOREACH></ul>
    }]



nx::mongo::Class create evp::DemandGood -superclass evp::Demand {
    :property amount:double,required
    :property supplied:double
    :property -incremental {supplies:embedded,type=::evp::SupplyGood,0..n ""}
    :method init {} {
        set sum 0
        if {[info exists :supplies]} {
            foreach s ${:supplies} {
                set sum [expr {$sum + [$s cget -amount]}]
            }
        }
        set :supplied $sum
        set :needed   [expr {${:amount} - ${:supplied}}]
    }
}


    forms modal add supply-good {
<div class="modal fade" tabindex="-1" role="dialog" id="$id">
    <div class="modal-dialog" role="document">
    <form role="form" method="post" action="">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">$title</h4>
      </div>
        <div class="modal-body">
            <div class="form-group">
              <label for="amount"><span class="glyphicon glyphicon-shopping-cart"></span> Amount</label>
              <input type="number" class="form-control" id="amount" name="amount" value="@:needed@" placeholder="Enter amount"
               min="0" max="@:needed@">
              <span class="validity"></span>
             </div>
             <input type='hidden' name='__id' value='@::_id@'>
             <input type='hidden' name='by_person' value='@::current_user_name@'>
             <input type='hidden' name='__context' value='$context'>
             <input type='hidden' name='__what' value='$what'>
             <input type='hidden' name='__action' value='$action'>
        </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
        <button type="submit" class="btn btn-primary" formaction="$href">Supply</button>
      </div>
     </div><!-- /.modal-content -->
     </form>
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
    }


set id     [ns_queryget __id]
set what   [ns_queryget __what ""]
set action [ns_queryget __action]

 switch [ns_queryget __action] {
     ...

     supply-good {
         set e [Event find first -cond [list _id = [ns_queryget __id]]]
         if {$e ne ""} {
             set demand_name [ns_queryget __context]
             set demand [find-demand $e $demand_name]
             $demand supplies add [SupplyGood new \
                                        -by_person [ns_queryget by_person] \
                                        -amount [ns_queryget amount]] end
             $e save
             ns_returnredirect $default_return_page
         }
     }
     ...
 }