Bladder Patrol
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This model simulates the lives of lunatics trapped in a hellish world. It is my first (and only) NetLogo model, written in 2012 shortly after I started work at the CCL on the NetLogo Development team, and loosely inspired by my day-to-day goings-on at work.
HOW IT WORKS
To begin, there are 5 players (differently-colored person sprites) standing at the center of the game canvas. As time elapses, the players' biological needs grow, based on values determined by the sliders. Generally, hunger and thirst rise over time, eventually reaching thresholds at which the needs must be addressed, lest the player die within a certain number of ticks (ghost sprite, body replaced by a flower sprite). A player wins the game when he/she is the last one left alive.
There are pretzels strewn about the canvas that can be used to reduce the accumulating hunger. If a player encounters a pretzel on the floor while hungry, he/she will eat it directly (Pacman icon). If a player encounters a pretzel on the floor while not hungry, he/she will hold onto it for possible later use (box icon). If a player grows hungry and has surplus pretzels, he/she will eat it (open box icon). If a player grows hungry and does not have any surplus pretzels, he/she will attempt to find a pretzel on the ground, or might approach a nearby player who has surplus pretzels and buy one (red dollar icon for buyer, green dollar icon for seller).
Eating pretzels, though, incurs thirst (which also accumulates over time). The water fountain (blue/gray water drop sprite) at the left side of the canvas is the only place where thirst can be quenched. The water fountain has a limited amount of water that replensishes over time. When there is enough water present in the fountain to help in quenching a thirsty, nearby player's thirst, he/she will attempt to drink the water (water bottle icon), lowering thirst. An unlimited number of players can drink from the fountain simulataneously.
Drinking water, though, incurs "tinkles"--a measure of the player's desire to urinate. The toilet on the right side of the canvas (toilet sprite) is the only place where tinkles can be safely diminished. However, only one player can use the toilet at a time. If a near-to-the-toilet player desires to urinate, and the toilet is unoccupied, the player may ascend the throne and reduce his/her tinkles over time (rocket icon).
If, however, the player keeps an elevated count of tinkles for a certain number of ticks, he/she will uncontrollably reduce his/her tinkle count by having a bladder explosion (yellow water drop sprite). Experiencing a bladder explosion forces a player to be fined (red dollar icon), since it is indecent to leave a mess of urine on the floor in a public place.
This public place, however, has a coyote problem, and coyotes have a tendency of marking their territory with their urine. After a player experiences a certain number of bladder explosions, a territorial, alpha male robot coyote with a laser cannon strapped to its back will appear from off-screen, dashing to the opposite side of the screen, and shooting the offending player to death with a laser on its way through.
Under ideal settings, the players will find "freetime", where all of his/her needs are sated and ticks can be spent on anything of the player's choosing.
If toilet-troll
is true
, one role-free player will be assigned the role of "toilet troll", causing him/her to, during freetime, hog the toilet as much as possible, possibly forcing other players to have unnecessary bladder explosions.
If pretzel-protector
is true
, one role-free player will be assigned the role of "pretzel protector", causing him/her to, during freetime, gather pretzels unnecessarily, possibly forcing other players to starve or need to buy pretzels from the protector.
If water-waster
is true
, one role-free player will be assigned the role of "water waster", causing him/her to, during freetime, drink from the water fountain unnecessarily, possibly forcing other players to die of thirst (due to a depleted water supply), and almost certainly causing the water waster to experience numerous bladder explosions quite quickly.
HOW TO USE IT
Click "Setup". Then, click "Go". I discourage you from turning up the speed slider much, because the most interesting part of the whole thing happens really quickly.
THINGS TO NOTICE
ZAP!
THINGS TO TRY
Play with all of the sliders. Less intimidatingly, try turning on the personalities (by using the switches in the top-right of the interface). The default settings for the model cause enabling "water waster" to have a profound impact on the game.
EXTENDING THE MODEL
People sit on the toilet out in the open, without any sort of privacy. Obviously, this is empiracally inaccurate and warrants improvement.
NETLOGO FEATURES
- Animated icons (
handle-anims
) - Solid-colored bar graphs (see both the code of the plot pens within the plots as well as the general boilerplate at the bottom of the "Code" tab (below the "Plotting Code" comment))
- Lasers (
direct-lasers
) List[T].take(n: Int): List[T]
=>take
List[T].zipWithIndex: List[(Int, T)]
=>zip-with-index
RELATED MODELS
No one dares make a mode related to my own.
CREDITS AND REFERENCES
Jason Bertsche IS AWESOME
Comments and Questions
breed [pretzels pretzel] pretzels-own [ owner-id ] breed [water-stands water-stand] water-stands-own [ id thirsties-on-tap ] breed [toilets toilet] toilets-own [ id is-occupied? ] breed [puddles puddle] breed [corpses corpse] corpses-own [ is-dead? ] breed [people person] people-own [ id pretzel-count thirsties hungries tinkles money ticks-hungry ticks-thirsty ticks-wanting-bathroom occupied-toilet-id bex-count did-buy-pretzel-this-tick? is-drinking? is-dead? specialty-type ] breed [lasers laser] lasers-own [ target-hunted ] breed [coyotes coyote] coyotes-own [ target-id exit-dir ] breed [pick-up-anims pick-up-anim] pick-up-anims-own [ ticks-alive j-dist ] breed [from-bag-anims from-bag-anim] from-bag-anims-own [ ticks-alive j-dist ] breed [drink-anims drink-anim] drink-anims-own [ ticks-alive j-dist ] breed [eat-anims eat-anim] eat-anims-own [ ticks-alive j-dist ] breed [money-plus-anims money-plus-anim] money-plus-anims-own [ ticks-alive j-dist ] breed [money-minus-anims money-minus-anim] money-minus-anims-own [ ticks-alive j-dist ] breed [bex-anims bex-anim] bex-anims-own [ ticks-alive j-dist ] breed [tinkle-anims tinkle-anim] tinkle-anims-own [ ticks-alive j-dist ] breed [death-anims death-anim] death-anims-own [ ticks-alive j-dist ] globals [ is-won? color-list player-count specialty-types toilet-troll-str pretzel-prot-str water-waster-str coyote-jump-dist coyote-laser-range laser-velocity anim-lifespan anims-list anim-float-rate ghost-float-rate rocket-float-rate anim-placement-above dollar-size default-anim-size ] to setup clear-all initialize make-turtles reset-ticks end to initialize set is-won? false set color-list [violet green red orange pink gray blue yellow brown white] set player-count 5 set toilet-troll-str "toilet-troll" set pretzel-prot-str "pretzel-protector" set water-waster-str "water-waster" set specialty-types (list toilet-troll-str pretzel-prot-str water-waster-str) set coyote-jump-dist 3 set coyote-laser-range 12 set laser-velocity 7 set anim-lifespan 5 set anims-list (list eat-anims money-plus-anims money-minus-anims drink-anims from-bag-anims pick-up-anims bex-anims tinkle-anims death-anims) set anim-float-rate .5 set ghost-float-rate 1 set rocket-float-rate 2 set anim-placement-above 2 set default-anim-size 2 end to go handle-anims handle-spoilers handle-water-level if ((count people = 1) and not is-won?) [ print (word (id-to-color-name ([id] of (one-of people))) " has won!") set is-won? true stop ] amplify-desires assess-desires spawn-new-pretzels spawn-new-coyotes direct-coyotes direct-lasers act-on-desires tick end to handle-anims foreach anims-list [ ask ? [ set ticks-alive (ticks-alive + 1) ifelse ((ticks-alive >= anim-lifespan) or ((max-pycor - ycor) <= j-dist)) [die] [jump j-dist] ] ] end to handle-spoilers ifelse (spoilers) [ ask people with [ specialty-type = water-waster-str ] [ ifelse (water-waster) [ set shape "water-waster" ] [ set shape "person" ] ] ask people with [ specialty-type = toilet-troll-str ] [ ifelse (toilet-troll) [ set shape "toilet-troll" ] [ set shape "person" ] ] ask people with [ specialty-type = pretzel-prot-str ] [ ifelse (pretzel-protector) [ set shape "pretzel-protector" ] [ set shape "person" ] ] ] [ ask people with [ specialty-type != -1 ] [ set shape "person" ] ] end to handle-water-level ask water-stands [ replenish-water determine-water-stand-shape ] end to replenish-water let inc water-replenishment-rate let thirsties-until-full (water-level-max - thirsties-on-tap) if (water-replenishment-rate > thirsties-until-full) [ set inc thirsties-until-full ] set thirsties-on-tap (thirsties-on-tap + inc) end ; For use by water-stands only to determine-water-stand-shape let percentage ((thirsties-on-tap / water-level-max) * 100) ifelse (percentage < 25) [ set shape "water0" ] [ ifelse (percentage < 50) [ set shape "water25" ] [ ifelse (percentage < 75) [ set shape "water50" ] [ ifelse (percentage < 100) [ set shape "water75" ] [ set shape "water100" ] ] ] ] end to spawn-new-pretzels let x (random (max-new-pretzels-per-tick - min-new-pretzels-per-tick)) let new-pretzel-count (x + min-new-pretzels-per-tick) create-pretzels new-pretzel-count [initialize-pretzel] end to spawn-new-coyotes if (bladder-explosion-threshold > 0) [ ask people with [ (bex-count >= bladder-explosion-threshold) and (not any? coyotes with [[id] of myself = target-id]) ] [ hatch-coyotes 1 [ let x -1 let y -1 let exit-on "null" let vertical (random 3) ifelse (vertical = 0) [ ; Baseline set x ((random (max-pxcor + (abs min-pxcor))) - (abs min-pxcor)) set y min-pycor set exit-on "top" ] [ ifelse (vertical = 1) [ ; Topline set x ((random (max-pxcor + (abs min-pxcor))) - (abs min-pxcor)) set y max-pycor set exit-on "bottom" ] [ let horizon (random 2) ifelse (horizon = 1) [ set x max-pycor set y ((random (max-pycor + (abs min-pycor))) - (abs min-pycor)) set exit-on "left" ] [ set x min-pycor set y ((random (max-pycor + (abs min-pycor))) - (abs min-pycor)) set exit-on "right" ] ] ] set target-id ([id] of myself) set exit-dir exit-on set size 4 setxy x y face myself ] ] ] end to direct-coyotes ask coyotes [ let hunteds (people with [id = [target-id] of myself]) ifelse (any? hunteds) [ let hunted (one-of hunteds) move-towards hunted if ((distance hunted) <= coyote-laser-range) [ hatch-lasers 1 [ face hunted set size 2.5 set target-hunted hunted ] ] ] [ let should-die false ifelse (exit-dir = "right") [ set heading 90 set should-die (coyote-jump-dist >= (max-pxcor - xcor)) ] [ ifelse (exit-dir = "left") [ set heading 270 set should-die (coyote-jump-dist >= (abs (xcor - min-pxcor))) ] [ ifelse (exit-dir = "top") [ set heading 0 set should-die (coyote-jump-dist >= (max-pycor - ycor)) ] [ if (exit-dir = "bottom") [ set heading 180 set should-die (coyote-jump-dist >= (abs (ycor - min-pycor))) ] ] ] ] if (should-die) [die] jump coyote-jump-dist ] ] end to direct-lasers ask lasers [ if ([is-dead?] of target-hunted) [die] let base-looks 3 let looks base-looks while [(looks > 0) and (target-hunted != nobody)] [ jump (laser-velocity / base-looks) if ((distance target-hunted) < 2) [ ask target-hunted [ print (word (id-to-color-name id) " died of LASERED!") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true ] die ] set looks (looks - 1) ] ] end to place-bladder-explosion hatch-puddles 1 [ set color yellow set ycor (ycor - 1.5) ] end to-report id-to-color-name [thing-id] let color-num (item (thing-id - 1) color-list) if color-num = 9.9 [ report "white" ] report item (color-num mod 10) base-colors end to amplify-desires ask people [ set thirsties (thirsties + thirst-rate) set hungries (hungries + hunger-rate) ] end to assess-desires ask people [ if (hungries >= hunger-activation-threshold) [ set ticks-hungry (ticks-hungry + 1) ] if (thirsties >= thirst-activation-threshold) [ set ticks-thirsty (ticks-thirsty + 1) ] if (tinkles >= tinkle-activation-threshold) [ set ticks-wanting-bathroom (ticks-wanting-bathroom + 1) ] if (ticks-hungry >= ticks-hungry-before-death) [ print (word (id-to-color-name id) " died of hunger") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true stop ] if (ticks-thirsty >= ticks-thirsty-before-death) [ print (word (id-to-color-name id) " died of thirst") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true stop ] if (ticks-wanting-bathroom >= ticks-before-bladder-explosion) [ place-bladder-explosion set bex-count (bex-count + 1) hatch-bex-anims 1 [ initialize-anim myself ] set money (money - fine-for-bladder-explosion) set ticks-wanting-bathroom 0 set tinkles 0 ] ] end to act-on-desires ask people [ ifelse (is-drinking?) [ do-thirst ] [ ifelse (did-buy-pretzel-this-tick?) [ set did-buy-pretzel-this-tick? false ] [ ifelse (occupied-toilet-id != -1) [do-use-toilet] [ ifelse (hungries >= hunger-activation-threshold) [ ifelse (thirsties >= thirst-activation-threshold) [ ; If closer to dying of hunger than of thirst ifelse ((ticks-hungry-before-death - ticks-hungry) < (ticks-thirsty-before-death - ticks-thirsty)) [do-hunger] [do-thirst] ] [do-hunger] ] [ ifelse (thirsties >= thirst-activation-threshold) [do-thirst] [ ifelse ((tinkles >= tinkle-activation-threshold) and not is-water-wasting?) [do-find-toilet] [ ifelse (is-toilet-trolling?) [do-find-toilet] [ ifelse (is-water-wasting?) [do-thirst] [ ifelse (is-pretzel-protecting?) [do-scavenge-pretzels] [ let pretzel-needer (find-nearest-pretzel-needer-with-money pretzel-selling-price) ifelse ((pretzel-count > 0) and (pretzel-needer != nobody) and (is-reachable? pretzel-needer)) [ do-sell-pretzel pretzel-needer ] [do-scavenge-pretzels] ] ] ] ] ] ] ] ] ] ] end ; For use by people only to-report find-nearest [targets] report min-one-of targets [distance myself] end to-report find-nearest-pretzel-needer-with-money [price] let needers (people with [(pretzel-count < 1) and (money >= price) and (myself != self)]) ifelse (any? needers) [ report find-nearest needers ] [ report nobody ] end ; For use by people only to-report is-reachable? [target] let dist ([distance target] of self) report (dist <= distance-travelable-per-tick) end ; For use by people only to move-towards [target] move-towards-dist target distance-travelable-per-tick end ; For use by people only to move-towards-dist [target dist] face target jump dist end ; For use by people only to move-randomly set heading (random 360) jump distance-travelable-per-tick end ; For use by people only to move-next-to [target] let dist-minus 2 let dist-to-target distance target let moving-dist (dist-to-target - dist-minus) if (0 > moving-dist) [move-towards-dist target moving-dist] end ; For use by people only to-report already-next-to? [target] report distance target <= 2 end ; For use by people only to consume-pretzel let bottomed-hungries 0 let unbottomed-hungries (hungries - pretzel-hunger-reduction) if (unbottomed-hungries > 0) [ set bottomed-hungries unbottomed-hungries ] set pretzel-count (pretzel-count - 1) set hungries bottomed-hungries set thirsties (thirsties + thirst-incurred-by-pretzels) if (hungries < hunger-activation-threshold) [ set ticks-hungry 0 ] end ; For use by people only to consume-water [nearest-water] let topped-on-tap water-thirst-reduction if (([thirsties-on-tap] of nearest-water) < water-thirst-reduction) [ set topped-on-tap ([thirsties-on-tap] of nearest-water)] show [thirsties-on-tap] of nearest-water let bottomed-thirsties 0 let unbottomed-thirsties (thirsties - topped-on-tap) if (unbottomed-thirsties > 0) [ set bottomed-thirsties unbottomed-thirsties ] let water-taken (topped-on-tap - bottomed-thirsties) if (water-taken < 0) [ set water-taken 0 ] ask nearest-water [ set thirsties-on-tap (thirsties-on-tap - water-taken) ] set thirsties bottomed-thirsties set tinkles (tinkles + tinkles-incurred-by-water) hatch-drink-anims 1 [ initialize-anim myself ] if (thirsties < thirst-activation-threshold) [ set ticks-thirsty 0 ] end ; For use by people only to do-use-toilet set tinkles (tinkles - tinkles-lost-per-tick-in-bathroom) hatch-tinkle-anims 1 [ initialize-rocket myself ] if (tinkles <= 0) [ set tinkles 0 ask toilets with [ id = [occupied-toilet-id] of myself ] [ set is-occupied? false ] set occupied-toilet-id -1 ] end ; For use by people only to do-hunger ifelse (pretzel-count > 0) [ consume-pretzel hatch-from-bag-anims 1 [ initialize-anim myself ] ] [ let nearest-pretzel (find-nearest pretzels) ifelse (nearest-pretzel != nobody) [ ifelse (is-reachable? nearest-pretzel) [ move-to nearest-pretzel ask nearest-pretzel [die] set pretzel-count (pretzel-count + 1) consume-pretzel hatch-eat-anims 1 [ initialize-anim myself ] ] [move-towards nearest-pretzel] ] [do-find-pretzel-seller] ] end ; For use by people only ; Does not accomodate for setups without water to do-thirst let nearest-water (find-nearest water-stands) ifelse (is-reachable? nearest-water) [ if (not already-next-to? nearest-water) [ move-next-to nearest-water ] consume-water nearest-water if (thirsties = 0) [ set is-drinking? false ] ] [ move-towards nearest-water ] end ; For use by people only to do-find-toilet let nearest-toilet (find-nearest toilets) ifelse (is-reachable? nearest-toilet) [ ifelse (not ([is-occupied?] of nearest-toilet)) [ do-occupy-toilet nearest-toilet ] [ move-next-to nearest-toilet ] ] [ move-towards nearest-toilet ] end ; For use by people only to do-sell-pretzel [buyer] print (word (id-to-color-name id) " sold a pretzel to " (id-to-color-name ([id] of buyer))) move-next-to buyer set pretzel-count (pretzel-count - 1) set money (money + pretzel-selling-price) hatch-money-plus-anims 1 [ initialize-anim myself ] ask buyer [ set pretzel-count (pretzel-count + 1) consume-pretzel hatch-money-minus-anims 1 [ initialize-anim myself ] set money (money - pretzel-selling-price) ] end ; For use by people only to do-scavenge-pretzels let nearest-pretzel (find-nearest pretzels) ifelse (nearest-pretzel != nobody) [ ifelse (is-reachable? nearest-pretzel) [ move-to nearest-pretzel set pretzel-count (pretzel-count + 1) ask nearest-pretzel [die] hatch-pick-up-anims 1 [ initialize-anim myself ] ] [ move-towards nearest-pretzel ] ] [move-randomly] end ; For use by people only to do-occupy-toilet [toilet] move-to toilet setxy (xcor - 0.4) (ycor + 0.6) set occupied-toilet-id ([id] of toilet) ask toilet [ set is-occupied? true ] do-use-toilet end ; For use by people only to do-find-pretzel-seller let nearest-seller (min-one-of people with [pretzel-count > 0] [distance self]) ifelse (nearest-seller != nobody) [ ifelse (is-reachable? nearest-seller) [ move-next-to nearest-seller ] [ move-towards nearest-seller ] ] [ move-randomly ] end ; For use by people only to-report is-toilet-trolling? report ((specialty-type = toilet-troll-str) and toilet-troll) end ; For use by people only to-report is-pretzel-protecting? report ((specialty-type = pretzel-prot-str) and pretzel-protector) end ; For use by people only to-report is-water-wasting? report ((specialty-type = water-waster-str) and water-waster) end ; Setup stuff to make-turtles let color-tuple-list (zip-with-index (take color-list player-count)) let toilet-count 1 let water-stand-count 1 let invalid-id -1 set-default-shape people "person" set-default-shape pretzels "pretzel" set-default-shape toilets "toilet" set-default-shape water-stands "drop" set-default-shape puddles "drop" set-default-shape corpses "flower" set-default-shape coyotes "coyote" set-default-shape lasers "lazor" set-default-shape eat-anims "pacman" set-default-shape money-plus-anims "green-dollar" set-default-shape money-minus-anims "red-dollar" set-default-shape drink-anims "bottle" set-default-shape from-bag-anims "opened-gift" set-default-shape pick-up-anims "gift" set-default-shape bex-anims "red-dollar" set-default-shape tinkle-anims "red-rocket" set-default-shape death-anims "ghost" create-pretzels (3 * player-count) [ initialize-pretzel ] create-toilets 1 [ set size 5 set heading 90 set id -1 set is-occupied? false jump 14 ] while [toilet-count > 0] [ ask one-of toilets with [ id = -1 ] [ set id toilet-count ] set toilet-count (toilet-count - 1) ] create-water-stands 1 [ set color blue set size 4 set heading 270 set thirsties-on-tap starting-water-level set id -1 jump 14 determine-water-stand-shape ] while [water-stand-count > 0] [ ask one-of water-stands with [ id = -1 ] [ set id water-stand-count ] set water-stand-count (water-stand-count - 1) ] create-ordered-people player-count [ jump 1.75 set size 2.5 set id invalid-id set pretzel-count starting-pretzels set thirsties ((random thirst-activation-threshold) + base-thirst) set hungries ((random hunger-activation-threshold) + base-hunger) set tinkles 0 set money starting-money set ticks-hungry 0 set ticks-thirsty 0 set ticks-wanting-bathroom 0 set occupied-toilet-id -1 set bex-count 0 set did-buy-pretzel-this-tick? false set is-drinking? false set is-dead? false set specialty-type -1 ] handle-specialty-types while [not (empty? color-tuple-list)] [ let head (first color-tuple-list) let tail (but-first color-tuple-list) ask one-of people with [ id = invalid-id ] [ set id ((first head) + 1) set color (first (but-first head)) ] set color-tuple-list tail ] end ; For use by pretzels only to initialize-pretzel set size 1.5 let angle (random 360) let dist (((random 1100) / 100) + 6) set heading angle set owner-id -1 jump dist end to handle-specialty-types let max-iters (length specialty-types) if (player-count < max-iters) [ set max-iters player-count ] let types (shuffle specialty-types) handle-specialty-types-helper types 0 max-iters end to handle-specialty-types-helper [types iters max-iters] if (iters < max-iters) [ ask one-of people with [specialty-type = -1] [ set specialty-type (first types)] handle-specialty-types-helper (but-first types) (iters + 1) max-iters ] end ; For use by anims only to initialize-anim [creator] initialize-anim-base creator anim-float-rate end to initialize-rocket [creator] initialize-anim-base creator rocket-float-rate end to initialize-ghost [creator] initialize-anim-base creator ghost-float-rate end to initialize-anim-base [creator jump-dist] set j-dist jump-dist set ticks-alive 0 set heading 0 set size default-anim-size move-to creator let new-ycor (ycor + anim-placement-above) if (new-ycor < max-pycor) [ set ycor new-ycor ] end to-report zip-with-index [xs] let indexes (n-values (length xs) [?]) report zip indexes xs end to-report zip [xs ys] report (map [list ?1 ?2] xs ys) end to-report take [xs num] report take-helper xs num [] end to-report take-helper [xs num acc] if-else num <= 0 or (empty? xs) [ report reverse acc ] [ report take-helper (but-first xs) (num - 1) (fput (first xs) acc) ] end ; +-------------------------+ ; | Plotting code | ; +-------------------------+ to plot-people-base [x plot-type is-border?] let my-turtle (one-of people with [id = (x + 1)]) let tx (get-true-x x) ifelse (my-turtle = nobody) [ plotxy tx 0 ] [ ifelse (is-border?) [ plot-switchboard tx plot-type my-turtle ] [ let i tx repeat (get-true-repeats x) [ plot-switchboard i plot-type my-turtle set i (i + .01) ] ] ] end to plot-switchboard [x plot-type my-turtle] let y (run-switchboard plot-type my-turtle) plotxy x y end to-report run-switchboard [plot-type my-turtle] report [runresult plot-type] of my-turtle end to plot-threshold [threshold] plotxy 0 threshold end to-report get-true-x [x] ifelse (x = 0) [report 0.02] [report x] end to-report get-true-repeats [x] ifelse x = 0 or x = player-count - 1 [report 97] [report 99] end
There is only one version of this model, created about 11 years ago by Jason Bertsche.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Bladder Patrol.png | preview | Preview for 'Bladder Patrol' | about 11 years ago, by Jason Bertsche | Download |
This model does not have any ancestors.
This model does not have any descendants.
Corey Brady
How do you do it? (Question)
impressed.
Posted about 11 years ago
Jason Bertsche
Re: How do you do it?
This is a skill that can no more be taught than "having three arms" can be taught.
Posted about 11 years ago