<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-21383536</id><updated>2011-12-29T11:12:44.220+02:00</updated><category term='taskboard'/><category term='sharepoint tfs'/><category term='sgza capetown za scrum gathering openspaces'/><category term='sharepoint'/><category term='za'/><category term='scrum'/><category term='tfs'/><category term='borisgloger'/><category term='office'/><category term='agile'/><category term='scrum gathering'/><category term='sugsa ba requirements'/><category term='talk'/><category term='capetown'/><category term='sugsa'/><category term='games'/><category term='dos'/><category term='xgame'/><category term='sqlserver c#'/><category term='sgza'/><category term='sgza scrum gathering capetown za'/><category term='estimation'/><title type='text'>Mind well</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://campey.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>41</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-21383536.post-4406955658243830558</id><published>2011-12-19T20:39:00.000+02:00</published><updated>2011-12-19T20:39:56.516+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sgza'/><title type='text'>Scrum Safari 2011: Lightning Talk Videos</title><content type='html'>On day 2 of the &lt;a href="http://campey.blogspot.com/2011/09/cape-town-scrum-gathering-2011-outline.html"&gt;Cape Town Scrum Gathering&lt;/a&gt; (a.k.a. Scrum Safari) there were a few lightning talks in the afternoon. I was lucky enough to nab the last slot.&lt;br /&gt;
&lt;p&gt;&lt;a href="https://twitter.com/#!/patrick_vine"&gt;Patrick Vine&lt;/a&gt;&amp;nbsp;was at hand to capture the talks and they were posted on vimeo by the &lt;a href="http://www.scrum.org.za/"&gt;sugsa&lt;/a&gt; committee.&lt;/p&gt;
&lt;p&gt;I've collated links to the talks on vimeo with my (somewhat terse) notes from the gathering.&lt;/p&gt;
&lt;h3&gt;Annu Augustine: Saying No&lt;/h3&gt;
&lt;p&gt;Step 1: Don't say the word no!&lt;br /&gt;Instead: not now, let's explore, what if?&lt;br /&gt;Listen, understand context, then use the same language&lt;br /&gt;To motivate prioritization, show lack of connection to the goal
&lt;br /&gt;&lt;a href="http://vimeo.com/29251667"&gt;Watch Saying No on vimeo&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Cara Turner: Achievable Goals&lt;/h3&gt;
&lt;p&gt;Maybe we achieved it?&lt;br /&gt;Cara took us through how to frame a goal to assist success.
&lt;br /&gt;&lt;a href="http://vimeo.com/29257791"&gt;Watch Achievable Goals on vimeo&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Brent: Agile Success&lt;/h3&gt;
&lt;p&gt;How to tame the dragon: we can't tame a two headed dragon&lt;br /&gt;Client induction is important to get on the same page&lt;br /&gt;Working software is different: "We don't build ships like this" -- indeed.
&lt;br /&gt;&lt;a href="http://vimeo.com/29257883"&gt;Agile Success&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;Pat Vine: Fixed Price Scrum&lt;/h3&gt;
&lt;p&gt;Why? The customer wants:&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;to know cost&lt;/li&gt;
&lt;li&gt;to reduce risk&lt;/li&gt;
&lt;li&gt;requirement for tender&lt;/li&gt;
&lt;/ul&gt;
Fixed cost helps some things: scope, date.&lt;br /&gt;Backlog management? + on the end&lt;br /&gt;
&lt;a href="http://vimeo.com/29254363"&gt;Watch Fixed Price Scrum on vimeo&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Carlo Kruger: Your sprint review sux&lt;/h3&gt;
&lt;p&gt;15 minute tester demo of the sprint!&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Ken_Schwaber"&gt;Ken&lt;/a&gt;: no applause please, we're just doing our job. If we pattern praise, bad things won't come out.&lt;br /&gt;Purpose of the review is to inspect and adapt the product, we need to be exposed to failure to expose learning.&lt;br /&gt;If we raise the stakes, we remove space. Rather remove untrusted people. &lt;br /&gt;We are inspecting the work of the whole team in a facilitated conversation.&lt;br /&gt;Format: Set stage, gather data, generate insight, choose focus.
&lt;br /&gt;&lt;a href="http://vimeo.com/29253187"&gt;Watch Your sprint review sux on vimeo&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;David Campey: Agile Contracting&lt;/h3&gt;&lt;p&gt;Check-in: who has seen their contract?&lt;br /&gt;There is a tension between customer collaboration and contract negotiation.&lt;br /&gt;We do team weeks with money for nothing, &lt;a href="http://www.unboxedconsulting.com/"&gt;unboxed&lt;/a&gt;&amp;nbsp;does pay for points, &lt;a href="http://www.scrumalliance.org/profiles/46-gabrielle-benefield"&gt;Gabby Benefield&lt;/a&gt;&amp;nbsp;is suggesting a series of fixed price projects.&lt;br /&gt;Some inspection of our contract.&lt;br /&gt;This talk relates to my &lt;a href="http://campey.blogspot.com/2011/06/agile-contracting.html"&gt;agile contracting series&lt;/a&gt;.
&lt;br /&gt;&lt;a href="http://vimeo.com/29254892"&gt;Watch Agile Contracting on vimeo&lt;/a&gt;
&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;All in all a great storm of lightning to spark off new ideas. See you at the next gathering?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4406955658243830558?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4406955658243830558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4406955658243830558' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4406955658243830558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4406955658243830558'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/12/scrum-safari-2011-lightning-talk-videos.html' title='Scrum Safari 2011: Lightning Talk Videos'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-9134192911813779925</id><published>2011-09-18T22:46:00.000+02:00</published><updated>2011-12-19T20:45:21.979+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sugsa'/><category scheme='http://www.blogger.com/atom/ns#' term='capetown'/><category scheme='http://www.blogger.com/atom/ns#' term='sgza'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Cape Town Scrum Gathering 2011: Outline</title><content type='html'>&lt;br /&gt;
All of us at Information Logistics took the break from routine to take part in the &lt;a href="http://www.scrum.org.za/gathering-2"&gt;Scrum Safari&lt;/a&gt;.&amp;nbsp;My mind's still processing the influx of conversations from last week's gathering in Somerset West.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" height="177" src="http://www.scrum.org.za/uploads/2011/06/Scrumbanner02.jpg" width="400" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Excellent event as usual, well done to the committee and everyone else who helped out in some way. And thanks to all who came along and made this event great.&lt;br /&gt;
&lt;br /&gt;
Outline of my experience (&lt;a href="http://www.scrum.org.za/gathering-2/speaker-information"&gt;speaker details&lt;/a&gt;):&lt;br /&gt;
&lt;br /&gt;
Day 1&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Welcome with Austin / Mitch&lt;/li&gt;
&lt;li&gt;Boris Gloger's keynote on Agile and Management&lt;/li&gt;
&lt;li&gt;Sigi's Leadership talk&lt;/li&gt;
&lt;li&gt;Manoj: "It's about the culture, stupid"&lt;/li&gt;
&lt;li&gt;Serious Play with Thorsten&lt;/li&gt;
&lt;li&gt;Evening chat&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Day 2&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Scrum clinic - was both doctor and patient&lt;/li&gt;
&lt;li&gt;&lt;a href="http://campey.blogspot.com/2011/12/scrum-safari-2011-lightning-talk-videos.html"&gt;Lightning talks&lt;/a&gt;&amp;nbsp;(with a pop-in at the Agile Jazz and Games sessions)&lt;/li&gt;
&lt;li&gt;Lean vs Agile keynote with [x]&lt;/li&gt;
&lt;li&gt;Team game of pool to wrap up&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-gPdXs9URY3Q/TnZV3GQYB3I/AAAAAAAAAKU/3nElIyzlsJc/s1600/IMAG1015.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="241" src="http://4.bp.blogspot.com/-gPdXs9URY3Q/TnZV3GQYB3I/AAAAAAAAAKU/3nElIyzlsJc/s320/IMAG1015.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This little red scrum user group book is already sporting twenty-five pages of notes to process, so I'll be attempting to linkify the above list with posts over the next few weeks.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-9134192911813779925?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/9134192911813779925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=9134192911813779925' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/9134192911813779925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/9134192911813779925'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/09/cape-town-scrum-gathering-2011-outline.html' title='Cape Town Scrum Gathering 2011: Outline'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-gPdXs9URY3Q/TnZV3GQYB3I/AAAAAAAAAKU/3nElIyzlsJc/s72-c/IMAG1015.jpg' height='72' width='72'/><thr:total>2</thr:total><georss:featurename>Erinvale Hotel, Lourensford Rd, Cape Town 7130, South Africa</georss:featurename><georss:point>-34.0785524 18.8689753</georss:point><georss:box>-34.1048559 18.8294933 -34.0522489 18.9084573</georss:box></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-5757083237934035782</id><published>2011-09-16T22:30:00.003+02:00</published><updated>2011-09-16T22:30:54.696+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='office'/><title type='text'>Day One at the Gatehouse</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;
For the last while we've been building and putting the finishing touches on our new offices at the Gatehouse in Century City.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-Pbn7iZSwkVM/TnOr8dsUcpI/AAAAAAAAAKM/HMcuRfbKej4/s1600/IMAG0341.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/-Pbn7iZSwkVM/TnOr8dsUcpI/AAAAAAAAAKM/HMcuRfbKej4/s320/IMAG0341.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
The main event is three 20 square metre team rooms. The rooms are visually connected with big glass windows but have closing doors for when things get rowdy (or sensitive).&lt;br /&gt;
&lt;br /&gt;
It's all shiny and new-smelling, the aircon/heating works wonderfully (how often do workspaces miss out on that crucial detail?!) and we have our foosball table plonked in the middle of the common area.&lt;br /&gt;
&lt;br /&gt;
Building has beautiful internal spaces, (scary) talking elevator, wheelchair accessibility, smart lighting, across the road from the Colosseum mini-mall and is a brief walk away from Canal Walk.&lt;br /&gt;
&lt;br /&gt;
Joy.&lt;br /&gt;
&lt;br /&gt;
Today was&amp;nbsp;officially my first full day at the new offices.&amp;nbsp;I spent today pairing with Luke on some enhancements to his project. We set up a mini task-board and happily hacked the day away.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-WxfWdNeaqRo/TnOvMhZv9TI/AAAAAAAAAKQ/QKhY9igh-uU/s1600/IMAG0392.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://3.bp.blogspot.com/-WxfWdNeaqRo/TnOvMhZv9TI/AAAAAAAAAKQ/QKhY9igh-uU/s320/IMAG0392.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Looking forward to growing our company in the new space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-5757083237934035782?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/5757083237934035782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=5757083237934035782' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5757083237934035782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5757083237934035782'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/09/day-one-at-gatehouse.html' title='Day One at the Gatehouse'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-Pbn7iZSwkVM/TnOr8dsUcpI/AAAAAAAAAKM/HMcuRfbKej4/s72-c/IMAG0341.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-7650339770722705069</id><published>2011-09-15T21:30:00.000+02:00</published><updated>2011-09-16T21:29:02.213+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sugsa'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>Our own medicine</title><content type='html'>This is the third in my &lt;a href="http://campey.blogspot.com/2011/06/agile-contracting.html"&gt;Agile Contracting series&lt;/a&gt;.&lt;br /&gt;
As with the previous post, this is a verbatim copy of my speech notes, with some mark-up.
&lt;br /&gt;
&lt;code&gt;[DL]&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;



It's about the Why&lt;/h2&gt;
Time for our own medicine [mime spoon] joke about mirroring.&lt;br /&gt;
&lt;br /&gt;
Well, we're working towards alignment, but we also feel the need for a contract.&lt;br /&gt;
&lt;br /&gt;
It's time for some of our own medicine. Bring out the User story. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-xxSnFk_-T2Q/TnJPw2yF1cI/AAAAAAAAAKE/jwowI88k8yw/s1600/2728096478_554e5768fd.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="246" src="http://2.bp.blogspot.com/-xxSnFk_-T2Q/TnJPw2yF1cI/AAAAAAAAAKE/jwowI88k8yw/s400/2728096478_554e5768fd.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;






User Stories&lt;/h2&gt;
If we were to write the user story for our contract what would it look like?&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;As a software developer, I want a contract, so that...&lt;/li&gt;
&lt;li&gt;As a team, we want a contract, so that...&lt;/li&gt;
&lt;li&gt;As a software company, I want a contract so that?&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Do we really know?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;code&gt;[ to C]&lt;/code&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://farm3.static.flickr.com/2115/5725641861_a36b7aefdb.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://farm3.static.flickr.com/2115/5725641861_a36b7aefdb.jpg" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;19th Century Contract&lt;br /&gt;
(picture by &lt;a href="http://www.flickr.com/photos/58558794@N07/"&gt;kladcat&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Okay, no fair. That's not a story, that's an epic.&lt;br /&gt;
&lt;br /&gt;
And we want the things we want in epics because.. well we're playing catch up, everone else has them.&lt;br /&gt;
&lt;br /&gt;
Everyone else has them so that makes it good? *side-eye* That's a discussion better left for later.&lt;br /&gt;
&lt;code&gt;[C]&lt;/code&gt;
&lt;br /&gt;
&lt;h2&gt;





Scary Power&lt;/h2&gt;
So we know the scary thing about user stories is: like goals, once we define them we set the ball in motion.&lt;br /&gt;
&lt;br /&gt;
We know the why and the what and the how will inevitably follow.&lt;br /&gt;
&lt;br /&gt;
So, let's see what this baby can do.&lt;br /&gt;
&lt;blockquote&gt;
As a team,&lt;br /&gt;
we want this,&lt;br /&gt;
so that this great thing happens.&lt;/blockquote&gt;
&lt;h2&gt;





Feel the power&lt;/h2&gt;
&lt;blockquote&gt;
As a team we want: access to a product owner&lt;br /&gt;
so that: we get answers and resolutions quickly and don't have to guess or debate&lt;/blockquote&gt;
How: add a clause to the contract!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
As a team we want: a variable backlog&lt;br /&gt;
So that: we can do what is actually needed as we discover it&lt;/blockquote&gt;
How: add a clause to the contract!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
As a team we want: an agile release plan&lt;br /&gt;
So that: the client can have expectations that match reality&lt;/blockquote&gt;
How: add a clause to the contract.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
As a team we want: anything&lt;br /&gt;
Because of this good reason&lt;/blockquote&gt;
How: Add a clause to the contract.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, what do these clauses look like? I'll tell you about ours soon.&lt;br /&gt;
First off, some more stories:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
As a board/person paying&lt;br /&gt;
I want to know when we will be expected to pay&lt;br /&gt;
so that I can budget and do financial calculations&lt;/blockquote&gt;
How: make it clear in the contract&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
As the end user&lt;br /&gt;
I want to play with the software early&lt;br /&gt;
so that I can stress less and get what I want&lt;/blockquote&gt;
How: expose delivery mechanisms in the contract.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We can really get our teeth into this product: "the contract" if we bring our formiddable armada to bear on it.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;





Behaviour Driven Development&lt;/h2&gt;
So, what's next? BDD... behaviour driven development.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-LHtLSAaBgxA/TnJRo_jqz9I/AAAAAAAAAKI/gREwWLQ00zw/s1600/3236641811_92aa29d49f.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/-LHtLSAaBgxA/TnJRo_jqz9I/AAAAAAAAAKI/gREwWLQ00zw/s320/3236641811_92aa29d49f.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Crazy Crayon Physics Scenario&lt;br /&gt;
(picture by &lt;a href="http://www.flickr.com/photos/slopjop/"&gt;slopjop&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
Given a team working on 2 week sprints&lt;br /&gt;
When the sprint commitment is not achieved&lt;br /&gt;
Then : these are penalties/discounts&lt;/blockquote&gt;
[discussion, examples]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Given a team on hourly Time &amp;amp; Materials&lt;br /&gt;
When we run a four week month and everything goes well&lt;br /&gt;
Then this is the process and financials&lt;/blockquote&gt;
[discussion, smiles]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Given a team paid on Time and Materials&lt;br /&gt;
When we get to April 2011 and everyone takes the gap and gets 2 weeks leave&lt;br /&gt;
Then how does this baby hold up&lt;/blockquote&gt;
[nervous laughter?, discussion]&lt;br /&gt;
And what happens to the release plan?
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Given a client with cash-flow problems&lt;br /&gt;
When they stop paying&lt;br /&gt;
Then what do we do?&lt;/blockquote&gt;
[explain illusion attern of decline, discussion]&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;





TDD&lt;/h2&gt;
The next tool we have is Test Driven Development.&lt;br /&gt;
&lt;br /&gt;
Pure TDD involves only writing a line of code if you can write a test that makes the product fail.&lt;br /&gt;
&lt;br /&gt;
So we use scenarios and more focused tests to actually create a contract from the ground up that is tested, testable and has no cruft.&lt;br /&gt;
&lt;br /&gt;
Then run that by a lawyer &lt;i&gt;with the tests&lt;/i&gt; and ask what extra tests you should add.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://campey.blogspot.com/2011/06/agile-contracting.html"&gt;Back to Agile Contracting series index.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-7650339770722705069?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/7650339770722705069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=7650339770722705069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7650339770722705069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7650339770722705069'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/09/our-own-medicine.html' title='Our own medicine'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-xxSnFk_-T2Q/TnJPw2yF1cI/AAAAAAAAAKE/jwowI88k8yw/s72-c/2728096478_554e5768fd.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-122099412776219462</id><published>2011-09-15T10:53:00.000+02:00</published><updated>2011-09-15T12:55:43.628+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='taskboard'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Done since last stand-up</title><content type='html'>In the past we've had the problem of "zoodling" at stand-up (&lt;a href="http://blog.crisp.se/2010/09/01/henrikkniberg/1283373060000"&gt;"What to do when scrum doesn't work"&lt;/a&gt;&amp;nbsp;Henrik Kniberg SG Cape Town 2010) because you're not quite sure which tasks you've done in the last 24 hours.&lt;br /&gt;
&lt;br /&gt;
One suggestion is only moving tasks in standup; I find this most unsatisfying. It's great to be able to move that damn task in the heady joy of your victory dance.&lt;br /&gt;
&lt;br /&gt;
A small innovation that has made a big difference on our task boards is adding a "Done since last stand-up" column. Move your item there on completion, and it sits there, glowing with goodness for all to see, until the next stand-up.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-EsMI-VS1m5M/TnG6lEt-0zI/AAAAAAAAAKA/jbRMjttIbUs/s1600/donesincelast.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="213" src="http://3.bp.blogspot.com/-EsMI-VS1m5M/TnG6lEt-0zI/AAAAAAAAAKA/jbRMjttIbUs/s320/donesincelast.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Done since last stand-up in action&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
At the next stand-up you just hunt for your initials in that column and you know what you've been doing.&lt;br /&gt;
&lt;br /&gt;
That is if you were actually working on tasks on the board, if not, well it helps to bring people back onto the board, we like our work to be visible.&lt;br /&gt;
&lt;br /&gt;
It also helps to make it visible when people have "gone dark" or their task is taking too long.&lt;br /&gt;
&lt;br /&gt;
And immediately after stand-up the tasks can all move into the Done column.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-122099412776219462?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/122099412776219462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=122099412776219462' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/122099412776219462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/122099412776219462'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/09/done-since-last-stand-up.html' title='Done since last stand-up'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-EsMI-VS1m5M/TnG6lEt-0zI/AAAAAAAAAKA/jbRMjttIbUs/s72-c/donesincelast.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-5202272225921696731</id><published>2011-07-17T18:57:00.006+02:00</published><updated>2011-07-17T19:24:04.976+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sugsa'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>The House of Agile</title><content type='html'>&lt;p&gt;&lt;em&gt;This post is still in progress, at the moment it's a lightly marked up copy of my full form speech draft of this section. I'll edit it at some point, but for now at least it's up :)&lt;/em&gt;&lt;/p&gt;

&lt;a href="http://campey.blogspot.com/2011/06/agile-contracting.html"&gt;Series intro&lt;/a&gt;

&lt;h2&gt;The House of Pain?&lt;/h2&gt;

&lt;p&gt;The first time I read the manifesto, well... [reverie]...&lt;/p&gt;

&lt;p&gt;Who here has read the manifesto? Can you remember the first time you read it?&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;"we are uncovering better ways of developing software by doing it and helping others do it."&lt;/p&gt;&lt;p&gt;
"Through this work we have come to value:"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Did you laugh when you read "working software over comprehensive documentation"?&lt;/p&gt;

&lt;p&gt;Did you take a hopeful breath when you read "individuals and interactions over processes and tools"?&lt;/p&gt;

&lt;p&gt;Did you shake your head ruefully at: "customer collaboration at contract negotiation"?&lt;/p&gt;

&lt;p&gt;Or feel frustrated and trapped at "responding to change over following a plan"?&lt;/p&gt;

&lt;p&gt;Maybe you felt exactly the opposite?&lt;/p&gt;

&lt;p&gt;Why is this first encounter with the manifesto such an emotional one?&lt;/p&gt;

&lt;p&gt;Each of these statements contains within it a tension, between open and free on the the one hand and shut and trapped on the other.&lt;/p&gt;

&lt;code&gt;[L]&lt;/code&gt;

&lt;h2&gt;Four Walls&lt;/h2&gt;

&lt;p&gt;We can view these things on the right as walls drawn in on a floorplan for an engagement. We have a choice how we build those walls.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are two extremes:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If we choose to build rigid solid, safe, fear-based, spike encrusted walls... we can build ourselves an amazing safe impenetrable, protected ... prison. And live in that prison for months, or years, walking around in the prison yard, feeling frustrated everytime the walls get in the way. But not really knowing what is wrong [ like neo in the matrix]&lt;/p&gt;

&lt;p&gt;If we choose to eschew, to disregard, walls entirely, we stand naked in the elements, without a roof over our heads and can end up wandering aimlessly in the wilderness. Like .. hippies flolloping on the hills of woodstock, hey it's fun, it's like cool, um, like what now? Of course, some well knit teams of marines can roam this wilderness, but even they long to have a roof over their heads every now and then.&lt;/p&gt;

&lt;p&gt;As neither of these is too attractive, what do we do?

&lt;p&gt;The Buddhists have a concept of right view: "to recognise our ignorance and humbly seek the middle path."

&lt;h2&gt;Walking through walls&lt;/h2&gt;

&lt;code&gt;[DL]&lt;/code&gt;

&lt;p&gt;Very philosophical, Lets make that more real: Riaan goes to visit his friend Lenny at work and starts to notice all the same patterns, but then... someone walks through a wall!&lt;/p&gt;

&lt;blockquote&gt;What? You can't just change the scope?
You fixed a bug without logging it?

That guy just walked through a wall!
&lt;code&gt;[gropes around]&lt;/code&gt;
"Hey, you have doors"
&lt;/blockquote&gt;

&lt;p&gt;Lenny looks at Riaan long and hard and says, "Uh, yeah, we can walk through walls here." Then to rub it in: "Sometimes we don't get to actually walk through the wall, but at least we can see through it.. we call this a window."&lt;/p&gt;

&lt;h2&gt;A False Dichotomy&lt;/h2&gt;

&lt;code&gt;[DC]&lt;/code&gt;

&lt;p&gt;So, these walls can work for us how..&lt;/p&gt; 

&lt;p&gt;If we look back at the manifesto:&lt;/p&gt;

&lt;blockquote&gt;Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over sticking to a plan
&lt;/blockquote&gt;

&lt;p&gt;A conclusion it that it is left or right. Or that we have to tread some sort of compromise between the two.&lt;/p&gt;

&lt;p&gt;This is a false dichotomy.&lt;/p&gt;

&lt;code&gt;[long pause]&lt;/code&gt;

&lt;h2&gt;Door and Window Makers&lt;/h2&gt;
&lt;code&gt;[C]&lt;/code&gt;

&lt;p&gt;The two don't necessarily contradict. The things on the right are walls, and if built correctly can support, facilitate and improve the flow of things on the left.&lt;/p&gt;

&lt;p&gt;The problem is the things on the right are often more tangible, sellable, productisable. We can really get lost in processes, tools, contract negotiation, plans, and documentation when dealing with customer. And we can build walls that disregard and limit the things on the left.&lt;/p&gt;

&lt;p&gt;This is why we have to keep these values in mind at every turn while designing and improving our houses.&lt;/p&gt;

&lt;p&gt;Scrum, xp and friends contain frameworks, patterns and methodologies of getting through or over walls, And sometimes.. a wrecking ball, sometimes an idea, and sometimes designs for doors and windows that we can build into these walls.&lt;/p&gt;

&lt;h2&gt;History Lesson&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;[UR, sit] [history lesson]&lt;/code&gt; snowbird, light, xp scrum, fowler on head, cockburn: lightweight lightweight.&lt;/p&gt;

&lt;p&gt;Here I related &lt;a href="http://agilemanifesto.org/history.html"&gt;the history of the manifesto&lt;/a&gt;, particularly that the manifesto is the meeting of the minds of the door and window makers, who sought to share and find the essence of their door and window patterns.&lt;/p&gt;

&lt;h2&gt;Alignment&lt;/h2&gt;

&lt;p&gt;The key to achieving success in all of this is recognising our values, recognising that we share those values [look SR] with the client, and making sure that our decisions to build are informed by our shared values.&lt;/p&gt;

&lt;code&gt;[DR]&lt;/code&gt;

&lt;p&gt;This is known as alignment. Long term relationships are built on alignment.&lt;/p&gt;

&lt;p&gt;In the words of Seth Godin: 
&lt;blockquote&gt;"Alignment isn't something you say. It's something you do. Alignment is demonstrated when you make the tough calls, when you see if the thing that matters the most to you is also the thing that matters the most to the other person."
&lt;/blockquote&gt;

&lt;p&gt;It's a search engine wanting to give you search results as much as you want to get them.&lt;/p&gt;

&lt;p&gt;Or a holistic market that wants to give you healthy food as much as you want to buy it.&lt;/p&gt;

&lt;p&gt;Or a software company that wants to give you great product as much as you want to buy it.&lt;/p&gt;


 &lt;h2&gt;And so?&lt;/h2&gt;
&lt;code&gt;[C]&lt;/code&gt;

&lt;p&gt;So how does this relate to contracting? We now have some background to how I think about these agile values and can now use this foundation to deliver some of our own medicine to the values. Then I'll show you what we do at IL and the financial bits.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-5202272225921696731?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/5202272225921696731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=5202272225921696731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5202272225921696731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5202272225921696731'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/07/house-of-agile.html' title='The House of Agile'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4473579288353164613</id><published>2011-06-10T21:11:00.006+02:00</published><updated>2011-12-20T09:12:11.280+02:00</updated><title type='text'>Agile Contracting</title><content type='html'>In this series of blog posts I'll be posting the content of my recent talk at &lt;a href="http://www.scrum.org.za/"&gt;SUGSA&lt;/a&gt; Cape Town. Read Cara Turner's &lt;a href="http://www.scrum.org.za/community/past-cpt-events/5-may-event-agile-contracting"&gt;Event Report&lt;/a&gt; for a good overview.&lt;br /&gt;
&lt;a href="http://3.bp.blogspot.com/-FbIly1ii4aI/TimKYQ8-X5I/AAAAAAAAAJ0/nLJDXB1uzWw/s1600/manifesto.jpg"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5632184958475722642" src="http://3.bp.blogspot.com/-FbIly1ii4aI/TimKYQ8-X5I/AAAAAAAAAJ0/nLJDXB1uzWw/s400/manifesto.jpg" style="cursor: hand; cursor: pointer; display: block; height: 219px; margin: 0px auto 10px; text-align: center; width: 386px;" /&gt;&lt;/a&gt;
&lt;br /&gt;
These posts will be mainly based on my original speech notes; &lt;strike&gt;the video with actual content will be up at some point soon&lt;/strike&gt;.&lt;br /&gt;
&lt;h2&gt;
Introduction&lt;/h2&gt;
My fellow software developers.&lt;br /&gt;
It gives me great joy to be looking out at people who care about getting better at creating software.&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/-MtXK_EY1a88/TimI1h3mNFI/AAAAAAAAAJk/DVIY_J4KgoU/s1600/sugsa-audience.jpg"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5632183262209520722" src="http://4.bp.blogspot.com/-MtXK_EY1a88/TimI1h3mNFI/AAAAAAAAAJk/DVIY_J4KgoU/s400/sugsa-audience.jpg" style="cursor: hand; cursor: pointer; display: block; height: 106px; margin: 0px auto 10px; text-align: center; width: 400px;" /&gt;&lt;/a&gt;

&lt;br /&gt;
Tonight I'll be talking about contracts. Huh? Has this guy not read the &lt;a href="http://agilemanifesto.org/"&gt;manifesto for agile software development&lt;/a&gt;? we should be talking about customer collaboration, not contract negotiation, right?&lt;br /&gt;
Maybe. Just maybe I'll show you how our contracts can facilitate customer collaboration.&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-TfPS6fejoZw/TimJW-6zxMI/AAAAAAAAAJs/AEUYLIaT2bA/s1600/taskboard.jpg"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5632183836943303874" src="http://2.bp.blogspot.com/-TfPS6fejoZw/TimJW-6zxMI/AAAAAAAAAJs/AEUYLIaT2bA/s400/taskboard.jpg" style="cursor: hand; cursor: pointer; float: left; height: 311px; margin: 0 10px 10px 0; width: 184px;" /&gt;&lt;/a&gt;&lt;br /&gt;
Tonight I will share with you 
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;some of my insights into the manifesto for agile software development,&lt;/li&gt;
&lt;li&gt;then give our contracts some of our own medicine, to see how we can get them to jump through hoops&lt;/li&gt;
&lt;li&gt;how this works at &lt;a href="http://www.informationlogistics.co.za/"&gt;Information Logistics&lt;/a&gt; and&lt;/li&gt;
&lt;li&gt;then finally present a few financial models that support agile contracting.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="clear: both;"&gt;
&lt;h2&gt;
Sections&lt;/h2&gt;
These will be linkified as soon as they're written, for now they're promises.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://campey.blogspot.com/2011/07/house-of-agile.html"&gt;House of agile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://campey.blogspot.com/2011/09/our-own-medicine.html"&gt;Our own medicine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Information Logistics &amp;mdash; &lt;a href="http://www.informationlogistics.co.za/company.html"&gt;company&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Financial Models &amp;mdash; graphs based on &lt;a href="http://agilesoftwaredevelopment.com/blog/peterstev/10-agile-contracts"&gt;Peter Stevens' 10 Contracts&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;h2&gt;
More talks&lt;/h2&gt;
I've subsequently presented some of this material as a &lt;a href="http://campey.blogspot.com/2011/12/scrum-safari-2011-lightning-talk-videos.html"&gt;lightning talk at Scrum Safari 2011&lt;/a&gt;. It's also been proposed as a topic at Agile Africa 2012&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4473579288353164613?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4473579288353164613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4473579288353164613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4473579288353164613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4473579288353164613'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/06/agile-contracting.html' title='Agile Contracting'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-FbIly1ii4aI/TimKYQ8-X5I/AAAAAAAAAJ0/nLJDXB1uzWw/s72-c/manifesto.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4407855461361719970</id><published>2011-05-02T23:26:00.008+02:00</published><updated>2011-05-03T02:22:57.770+02:00</updated><title type='text'>GAE on Hudson with Mercurial &amp; Bitbucket</title><content type='html'>This post details getting &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt; to automatically poll a &lt;a href="https://bitbucket.org/"&gt;bitbucket&lt;/a&gt; &lt;a href="http://mercurial.selenic.com/"&gt;mercurial&lt;/a&gt; repository and deploy the &lt;a href="http://code.google.com/appengine/"&gt;google app engine&lt;/a&gt; &lt;a href="http://code.google.com/appengine/docs/python/gettingstarted/helloworld.html"&gt;python hello world&lt;/a&gt; project.
&lt;h2&gt;Debian install&lt;/h2&gt;

Just installed hudson on our Debian Lenny box using these &lt;a href="http://wiki.hudson-ci.org/display/HUDSON/Installing+Hudson+on+Ubuntu"&gt;useful aptitude instructions&lt;/a&gt;.

&lt;h2&gt;hg plugin&lt;/h2&gt;

&lt;p&gt;To get the plugin to install, go to the Hudson admin page, and manage plugins, then select available plugins. You should see ... nothing!&lt;/p&gt;

&lt;p&gt;A careful reading of &lt;a href="http://wiki.hudson-ci.org/display/HUDSON/Plugins"&gt;installing plugins&lt;/a&gt; hints that this is expected behaviour, since hitting this page starts the download and a restart is required to see the plugins.&lt;/p&gt;
&lt;p&gt;In my case a reload of the page was sufficient and, then I had the long, long, list of plugins available.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-BtpmKjoAjIM/Tb9Kqt4Ix1I/AAAAAAAAAJE/V1M3iymBVCw/s1600/hudson-mercurial.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 391px;" src="http://4.bp.blogspot.com/-BtpmKjoAjIM/Tb9Kqt4Ix1I/AAAAAAAAAJE/V1M3iymBVCw/s400/hudson-mercurial.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5602278559202199378" /&gt;&lt;/a&gt;
&lt;p&gt;Tick box, click install, see the above success screen.&lt;/p&gt;
&lt;p&gt;Click button, restart hudson, ready to go.&lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;This required some playing about, I was trying to do as little as possible; as it turns out I haven't needed the jdk or any of the other config paths, just click create new job.&lt;/p&gt;
&lt;p&gt;After entering the details of my bitbucket repo (and turning off private, have to figure out login), setting it to poll the repo, and figuring out an appropriate shell command, e.g. &lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;/home/campey/google_appengine/appcfg.py update $WORKSPACE --email=dev.campey@gmail.com --passin &lt; /home/campey/dev.campey.password&lt;/code&gt;&lt;/blockquote&gt;
&lt;p&gt;the build runs on save! And fails &amp;mdash; red globe!&lt;/p&gt;
&lt;p&gt;First run failed because I hadn't changed the app name. So back to app.yaml, edit, &lt;code&gt;hg commit&lt;/code&gt;, wait, ... and blue globe!&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-lf39TFPmI5U/Tb9FaGl1dBI/AAAAAAAAAI8/-jWZ8yiEsyQ/s1600/hudson-history.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 382px; height: 105px;" src="http://3.bp.blogspot.com/-lf39TFPmI5U/Tb9FaGl1dBI/AAAAAAAAAI8/-jWZ8yiEsyQ/s400/hudson-history.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5602272776220406802" /&gt;&lt;/a&gt;
&lt;p&gt;Yay!&lt;/p&gt;
&lt;p&gt;Next steps: getting the dev server to daemonize for local/grid testing.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4407855461361719970?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4407855461361719970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4407855461361719970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4407855461361719970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4407855461361719970'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2011/05/gae-on-hudson-with-mercurial-bitbucket.html' title='GAE on Hudson with Mercurial &amp; Bitbucket'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-BtpmKjoAjIM/Tb9Kqt4Ix1I/AAAAAAAAAJE/V1M3iymBVCw/s72-c/hudson-mercurial.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-6202978159330220493</id><published>2010-09-05T21:45:00.011+02:00</published><updated>2010-10-11T16:41:49.846+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='za'/><category scheme='http://www.blogger.com/atom/ns#' term='capetown'/><category scheme='http://www.blogger.com/atom/ns#' term='borisgloger'/><category scheme='http://www.blogger.com/atom/ns#' term='sgza'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum gathering'/><category scheme='http://www.blogger.com/atom/ns#' term='estimation'/><title type='text'>Magic Estimation</title><content type='html'>&lt;p&gt;In &lt;a href="http://borisgloger.com/"&gt;Boris Gloger&lt;/a&gt;'s "Estimation in Depth" deep dive at the &lt;a href="http://southafrica.scrumgathering.org/"&gt;South African Scrum Gathering&lt;/a&gt; he introduced us to Magic estimation.&lt;/p&gt;

&lt;h3&gt;Intro&lt;/h3&gt;

&lt;p&gt;Boris introduced it a little something like this:&lt;/p&gt;

&lt;blockquote&gt;So you've got a backlog of about 100-200 items and you have a backlog estimation meeting. First thing to do is put a numerical estimate on everything in the backlog. Using magic estimation this should take 10-15 minutes.&lt;/blockquote&gt;

&lt;p&gt;At which most of the room burst into laughter.&lt;/p&gt;

&lt;p&gt;I mean, he's got to be kidding, right? Estimation is a slog of negotiation and explanation preceding multiple rounds of &lt;a href="http://www.planningpoker.com/"&gt;planning poker&lt;/a&gt;. 1-3 minutes an item if  you're &lt;a href="http://www.urbandictionary.com/define.php?term=cooking%20on%20gas"&gt;cooking on gas&lt;/a&gt;.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/TIP7kwmen0I/AAAAAAAAAHw/LcPR-ZvzS8Q/s1600/P9010213.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/TIP7kwmen0I/AAAAAAAAAHw/LcPR-ZvzS8Q/s400/P9010213.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5513526977771773762" /&gt;&lt;/a&gt;

&lt;p&gt;Well, we left the deep dive room for a patch of floor and the results were... astounding. Okay, I'll say it: magic.&lt;/p&gt;

&lt;h3&gt;Function of Estimation&lt;/h3&gt;

&lt;p&gt;At the bar that evening, I found myself explaining it as follows.&lt;/p&gt;

&lt;p&gt;Estimation is a function that maps stories to complexity. Poker is one algorithm for the mapping, magic is another.&lt;/p&gt;
&lt;blockquote&gt;estimation ( story ) = complexity&lt;/blockquote&gt;
&lt;p&gt;Poker is an algorithm in which the whole team engages with each item sequentially, having an up-front discussion to attempt to have a good understanding and thus have an agreement when the cards are revealed.&lt;/p&gt;
&lt;p&gt;Magic estimation is then a kind of parallel sort, each actor applying his internal evaluation function to the set.&lt;/p&gt;
&lt;p&gt;And it happens in silence.&lt;/p&gt;
&lt;p&gt;It starts out with each actor sorting his subset into complexity point bins, then each actor evaluates the full set (already estimated by at least one team member) and moves only those that appear to be anomalies. As the process iterates, convergence is reached as we find stable points that all internal models can agree on.&lt;/p&gt;
&lt;h3&gt;Mechanism&lt;/h3&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/TIP8xzYFKQI/AAAAAAAAAH4/Iwtrr08e000/s1600/P9020227+crop.jpg"&gt;&lt;img style="float:right; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 325px; height: 400px;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/TIP8xzYFKQI/AAAAAAAAAH4/Iwtrr08e000/s400/P9020227+crop.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5513528301366618370" /&gt;&lt;/a&gt;&lt;p&gt;The "magic estimation check list" was put together by Gennine and Alister in our output session and is a good summary of the rules of the game.&lt;/p&gt;
&lt;p&gt;The image to the right is their flip-chart poster. I've repeated their points with some elaboration below.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start with the Product Backlog of user stories&lt;/li&gt;
&lt;li&gt;Team will play, product owner will watch (and learn)&lt;/li&gt;
&lt;li&gt;Lay the estimation estimation cards down on the floor, spaced out as per their values (as in the perspective picture above) e.g. &lt;pre&gt;123 5  8    13     20                   40&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Hand out user stories to team&lt;/li&gt;
&lt;li&gt;Explain rules: no talking, no non-verbal communication&lt;/li&gt;
&lt;li&gt;Each team member estimates, place stories at points&lt;/li&gt;
&lt;li&gt;Each team member checks estimates, re-estimate and move if desired (once all own cards are down)&lt;/li&gt;
&lt;li&gt;Product owner marks fall-outs (too large or keeps bouncing)&lt;/li&gt;
&lt;li&gt;Discuss fall-outs until reach agreement&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Estimation is done!! It's surprising when you get to the end, and that's it.&lt;/p&gt;
&lt;p&gt;A final check if anyone has a burning need to move any items helps to get everyone to realise they're happy with the result.&lt;/p&gt;
&lt;h3&gt;Fall-Outs&lt;/h3&gt;
&lt;p&gt;A bit more on the fall outs from point 8.&lt;/p&gt;
&lt;center&gt;&lt;img src="http://www.informationlogistics.co.za/eureka.gif"&gt;&lt;/img&gt;&lt;/img&gt;&lt;/center&gt;
&lt;p&gt;Some stories start to bounce around like oscillators from &lt;a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life"&gt;Conway's Game of Life&lt;/a&gt;, the product owner must watch for these and pull them out for more explanation. Once the game is done, the team can investigate what the differences of opinion were and get clarification from the product owner. I've tried switching to poker at this point, which has worked quite well.&lt;/p&gt;
&lt;p&gt;Some stories make their way out to the 100+ boundary. When stories end up here, the product owner pulls these out too. These need either: explanation from the product owner to break down the confusion that led to the high complexity, or breaking down into estimable chunks.&lt;/p&gt;

&lt;h3&gt;vs Poker&lt;/h3&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/TIP90cpNUDI/AAAAAAAAAIA/afXzxaZtJOY/s1600/P9010214.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 300px; height: 400px;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/TIP90cpNUDI/AAAAAAAAAIA/afXzxaZtJOY/s400/P9010214.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5513529446315675698" /&gt;&lt;/a&gt;
&lt;p&gt;Before trying it, I'd thought it would be okay, but not as good as poker at getting to good estimates.&lt;/p&gt;
&lt;p&gt;Now, I feel it's as good if not better than poker at getting to estimates. Poker does foster communication, but this can be done independently of estimation if you're doing magic.&lt;/p&gt;
&lt;p&gt;Avoiding the conversations of poker allows us to avoid arguments and, in the words of Oscar Wilde, &lt;blockquote&gt;"Arguments are to be avoided; they are always vulgar and &lt;span style="font-style:italic;"&gt;often convincing&lt;/span&gt;."&lt;/blockquote&gt; Without the convincing influence, magic estimation is able to capture each team member's instant conclusions that Malcolm Gladwell discusses in &lt;a href="http://www.gladwell.com/blink/index.html"&gt;Blink&lt;/a&gt;, then get all of those to agree. Or disagree.&lt;/p&gt;
&lt;p&gt;Being part of a complex dynamic system feels like a kind of magic as it converges. Getting to this picture with around 80 items in about 5 minutes... was magic!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-6202978159330220493?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/6202978159330220493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=6202978159330220493' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6202978159330220493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6202978159330220493'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/09/magic-estimation.html' title='Magic Estimation'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/TIP7kwmen0I/AAAAAAAAAHw/LcPR-ZvzS8Q/s72-c/P9010213.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-9185001387135034930</id><published>2010-09-02T23:05:00.003+02:00</published><updated>2010-09-02T23:18:03.380+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sgza capetown za scrum gathering openspaces'/><title type='text'>Open Space @ CPT Gathering</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/TIASI0fP8KI/AAAAAAAAAGQ/UCJjyenujYk/s1600/P9020260.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 172px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/TIASI0fP8KI/AAAAAAAAAGQ/UCJjyenujYk/s400/P9020260.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5512425886639452322" /&gt;&lt;/a&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Open_Space_Technology"&gt;open space&lt;/a&gt; marketplace in action this morning at the Cape Town Scrum Gathering. Fun being part of a complex dynamic system.&lt;/p&gt;
&lt;p&gt;Sessions I convened today:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agile contracting&lt;/li&gt;
&lt;li&gt;Job swapping (bus 2 bus) for cross pollination&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sessions I attended, paraphrased:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Extreme public openness; what (code, practice) should we share?&lt;/li&gt;
&lt;li&gt;Team psychology&lt;/li&gt;
&lt;li&gt;Wildcard ad-hoc group&lt;/li&gt;
&lt;li&gt;Trust&lt;/li&gt;
&lt;li&gt;Working environments&lt;/li&gt;
&lt;li&gt;Feeling oppressed? Let's make a play. w/ Alan Cyment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Will be attempting to blog my notes and impressions from these "soon". Looking forward to getting all of the scribe's notes from the day.&lt;/p&gt;
&lt;p&gt;Second half to an excellent gathering. Well done &lt;a href="http://www.scrum.org.za/"&gt;sugsa&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-9185001387135034930?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/9185001387135034930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=9185001387135034930' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/9185001387135034930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/9185001387135034930'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/09/open-space-cpt-gathering.html' title='Open Space @ CPT Gathering'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/TIASI0fP8KI/AAAAAAAAAGQ/UCJjyenujYk/s72-c/P9020260.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-3411617111351260612</id><published>2010-09-02T07:44:00.004+02:00</published><updated>2010-09-02T08:02:33.410+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sgza scrum gathering capetown za'/><title type='text'>Cape Town Scrum Gathering</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/TH8510bXsYI/AAAAAAAAAGI/KujgQVrtFqc/s1600/P9020233.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 237px;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/TH8510bXsYI/AAAAAAAAAGI/KujgQVrtFqc/s400/P9020233.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5512188065694069122" /&gt;&lt;/a&gt;
&lt;p&gt;Cape Town gathering day 1 concluded in a networking event where I caught a few moments of Henrik's improv on the baby grand at the Westin Grand.&lt;/p&gt;
&lt;p&gt;Before I plunge into day 2, a sketch of what stood out on day 1.&lt;/p&gt;
&lt;h3&gt;Henrik's Keynote&lt;/h3&gt;&lt;p&gt;&lt;a href="http://www.crisp.se/henrik.kniberg"&gt;Henrik Kniberg&lt;/a&gt;'s keynote was excellent, setting the tone for the gathering. He revisited the core scrum values (not the agile values) with frequent references to the "&lt;a href="http://www.amazon.co.uk/Agile-Software-Development-SCRUM-Schwaber/dp/0130676349"&gt;black book&lt;/a&gt;" and closed by stoking the scrumban fire a bit.&lt;/p&gt;
&lt;h3&gt;Deep dive: Boris Gloger&lt;/h3&gt;
&lt;p&gt;Estimation in depth. Wow, &lt;a href="http://borisgloger.com/"&gt;Boris&lt;/a&gt; broke my brain in three fabulous ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Magic estimation &amp;mdash; parallel sorting algorithm to achieve estimation of hundreds of items in minutes.&lt;/li&gt;
&lt;li&gt;Contracting on business value, not time and materials &amp;mdash; with an exit for the client if they're satisfied before the fixed cost is reached.&lt;/li&gt;
&lt;li&gt;Changing Level of Done - choose the set of constraints (definition of done) that allow you to start delivering features, then change the constraints and get everything to done again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;More to come. Off to the wildcard that is open spaces!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-3411617111351260612?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/3411617111351260612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=3411617111351260612' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3411617111351260612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3411617111351260612'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/09/cape-town-scrum-gathering.html' title='Cape Town Scrum Gathering'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PyasagsZ3QA/TH8510bXsYI/AAAAAAAAAGI/KujgQVrtFqc/s72-c/P9020233.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-8985234097847047659</id><published>2010-08-31T19:37:00.006+02:00</published><updated>2010-08-31T22:37:32.405+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sugsa ba requirements'/><title type='text'>Requirements Management</title><content type='html'>&lt;span style="font-style:italic;"&gt;&lt;a href="http://za.linkedin.com/pub/mohamed-bray/4/554/175"&gt;Mohamed Bray&lt;/a&gt; &lt;a href="http://www.scrum.org.za/events/requirements-management"&gt;Sugsa August 2010&lt;/a&gt;&lt;/span&gt;

&lt;p&gt;This month's sugsa was a cross-talk from the Business Analysis community.&lt;/p&gt;

&lt;h2&gt;The Talk&lt;/h2&gt;

&lt;p&gt;Mohamed described an iterative process as just multiple quick failures (wagile, thanks &lt;a href="http://scrumcoaching.wordpress.com/"&gt;Karen&lt;/a&gt;), if we decide to skimp on requirements. His stat was that 70% of defects are injected during the requirements phase. After gathering, the challenge becomes requirements management and &lt;em&gt;communication&lt;/em&gt;. This communication is difficult because the audience is broad and diverse.&lt;/p&gt;

&lt;p&gt;Requirements communication should have a few characteristics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;connect: we need collaboration and traceability&lt;/li&gt;
&lt;li&gt;actionable: when is it done? get commitment (intention ≠ commitment)&lt;/li&gt;
&lt;li&gt;units: time &amp; money&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Communication is not just representation.&lt;/p&gt;

&lt;h3&gt;Babok&lt;/h3&gt;

&lt;p&gt;Interesting (and new) fact to me is the existence of the  &lt;a href="http://www.theiiba.org/AM/Template.cfm?Section=Body_of_Knowledge"&gt;Business Analysis Body of Knowledge&lt;/a&gt; (BABOK). Although the $30 pdf ($60 for print) price has put it onto my library backlog, and not too near the top.&lt;/p&gt;

&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Traceability&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://za.linkedin.com/in/peterhundermark"&gt;Peter Hundermark&lt;/a&gt; probed a bit on whether traceability was really important.&lt;/p&gt;
&lt;p&gt;To me, as a developer, traceability had always meant the lengthy and painful process at the end of waterfall where we point to screens an show where each feature can be found.&lt;/p&gt;
&lt;p&gt;Mohamad extended this backwards to linking requirements to stakeholders and the origin of the item, so that we can get feedback on the intention when required. "Where it came from and where it went". Which is actually quite appealing.&lt;/p&gt;
&lt;h3&gt;BA Smells&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.scrumalliance.org/profiles/50963-marius-de-beer"&gt;Marius de Beer&lt;/a&gt; was looking for the "smells" or indicators that BA has gone bad.&lt;/p&gt;
&lt;p&gt;Requirements that are not quick to apprehend are smelly. They should be easy to interpret upfront. In that context, 90% of requirements are not clear. As an example, when we talk about oranges, you should get a vivid picture of an orange in your head.&lt;/p&gt;
&lt;h3&gt;Context-free&lt;/h3&gt;
&lt;p&gt;Asking context free questions is a technique to probe further while attempting to listen with a solution in mind.&lt;/p&gt;
&lt;h2&gt;Parting thought&lt;/h2&gt;
&lt;p&gt;The difference between regular analysts and BBND analysts (Mohamad's employer) is that they are 100% responsible for delivery.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-8985234097847047659?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/8985234097847047659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=8985234097847047659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8985234097847047659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8985234097847047659'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/08/requirements-management.html' title='Requirements Management'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-7646241207170936808</id><published>2010-06-07T20:26:00.006+02:00</published><updated>2010-06-07T20:52:01.048+02:00</updated><title type='text'>Intellisense: Re-show info</title><content type='html'>&lt;h3&gt;Complete Word&lt;/h3&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/TA0-fFET74I/AAAAAAAAAFw/cPBRW8OsEKc/s1600/CompleteWord.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 232px; height: 60px;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/TA0-fFET74I/AAAAAAAAAFw/cPBRW8OsEKc/s400/CompleteWord.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5480105025236889474"&gt;&lt;/a&gt;
&lt;p&gt;A long while back I included the "Complete Word" shortcut:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl-Space&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in my coding practice, avoiding the tricks I had developed to prompt the visual studio intellisense back into giving me suggestions for word completion.&lt;/p&gt;

&lt;p&gt;This saves a lot of "micro-time" and improves flow.&lt;/p&gt;

&lt;h3&gt;Parameter Info&lt;/h3&gt;

&lt;p&gt;Another time when I found myself coaching intellisense is when looking at the parameter info. This would be achieved, e.g. by re-typing a comma or the opening &lt;code&gt;(&lt;/code&gt; of a method call.&lt;/p&gt;

&lt;p&gt;On Friday I realised there had to be a keyboard short-cut, tonight I &lt;a href="http://www.mobydisk.com/softdev/techinfo/dotnetkeyboard.html"&gt;hunted&lt;/a&gt;, and found the treasure:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl-Shift-Space&lt;/code&gt;&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/TA0_PMd40FI/AAAAAAAAAF4/--qg9uqZYPw/s1600/ParameterInfo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 57px;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/TA0_PMd40FI/AAAAAAAAAF4/--qg9uqZYPw/s400/ParameterInfo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5480105851856932946" /&gt;&lt;/a&gt;

&lt;p&gt;Ahhh, the joy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-7646241207170936808?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/7646241207170936808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=7646241207170936808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7646241207170936808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7646241207170936808'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/06/intellisense-re-show-info.html' title='Intellisense: Re-show info'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/TA0-fFET74I/AAAAAAAAAFw/cPBRW8OsEKc/s72-c/CompleteWord.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-8685387830589084291</id><published>2010-05-12T12:53:00.005+02:00</published><updated>2010-05-20T12:36:26.482+02:00</updated><title type='text'>SQL XML Element contents from varchar column</title><content type='html'>&lt;h2&gt;The problem&lt;/h2&gt;

Stored in a varchar column, &lt;code&gt;payload_xml&lt;/code&gt;, we have xml that looks something like this:

&lt;code&gt;&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-16&amp;quot;?&amp;gt;  
&amp;lt;ReceiveMoneyParameters 
  xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;    
  ...
  &amp;lt;PaymentArrangementExternalReference&amp;gt;
    &lt;u&gt;JT00009084&lt;/u&gt;
  &amp;lt;/PaymentArrangementExternalReference&amp;gt;    
  ...
&amp;lt;/ReceiveMoneyParameters&amp;gt;
&lt;/pre&gt;&lt;/code&gt;


I need to return the underlined section as a varchar.

&lt;h2&gt;The solution&lt;/h2&gt;

With the help of Tim Chapman's article &lt;a href="http://articles.techrepublic.com.com/5100-10878_11-6140404.html"&gt;Shred XML data with XQuery&lt;/a&gt;, I've arrived at the following code:

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
 font-size: small;
 color: black;
 font-family: Consolas, "Courier New", Courier, Monospace;
 background-color: #ffffff;
 /*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt 
{
 background-color: #f4f4f4;
 width: 100%;
 margin: 0em;
}

.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;select cast&lt;/span&gt;(&lt;span class="kwrd"&gt;cast&lt;/span&gt;(&lt;span class="kwrd"&gt;cast&lt;/span&gt;(payload_xml &lt;span class="kwrd"&gt;as&lt;/span&gt; nvarchar(&lt;span class="kwrd"&gt;max&lt;/span&gt;)) &lt;span class="kwrd"&gt;as&lt;/span&gt; xml)
.query(&lt;span class="str"&gt;'data(//ReceiveMoneyParameters/PaymentArrangementExternalReference)'&lt;/span&gt;)
&lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;max&lt;/span&gt;)) &lt;span class="kwrd"&gt;as&lt;/span&gt; PaymentArrangementExternalReference,&lt;/pre&gt;

Which is, admittedly a bit of a mess, but each part has its purpose, and it works!

&lt;h2&gt;Observations&lt;/h2&gt;
Interesting observations from inside out:
&lt;ul&gt;
&lt;li&gt;cast as &lt;code&gt;nvarchar&lt;/code&gt; so that the encoding matches &lt;code&gt;"utf-16"&lt;/code&gt;&lt;/li&gt; otherwise sql server fails with the cryptic '&lt;code&gt;XML parsing: ... unable to switch the encoding&lt;/code&gt;'
&lt;li&gt;&lt;code&gt;data()&lt;/code&gt; function returns the actual content of the node, not the whole node&lt;/li&gt;
&lt;li&gt;I didn't need to use &lt;code&gt;[]&lt;/code&gt; indexers because there is only one element.&lt;/li&gt;
&lt;/ul&gt;

Lesson learned: use the xml datatype for the column.

&lt;h2&gt;Update&lt;/h2&gt;
&lt;p&gt;To handle different namespaces, e.g.&lt;/p&gt;
&lt;pre&gt;  &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-16&amp;quot;?&amp;gt;
  &amp;lt;PremiumDistributionRequest 
   xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; 
   xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;
    &amp;lt;Payment&amp;gt;
      &amp;lt;PaymentId 
       xmlns=&amp;quot;http://il.net.za/Agreement/Payment&amp;quot;&amp;gt;
        &lt;u&gt;14079&lt;/u&gt;
      &amp;lt;/PaymentId&amp;gt;
 &lt;/pre&gt;


&lt;p&gt;add a namespace declaration to the query as follows:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
 font-size: small;
 color: black;
 font-family: Consolas, "Courier New", Courier, Monospace;
 background-color: #ffffff;
 /*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt 
{
 background-color: #f4f4f4;
 width: 100%;
 margin: 0em;
}

.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;select&lt;/span&gt; @x.query(
  &lt;span class="str"&gt;'declare namespace ap="http://il.net.za/Agreement/Payment";
  data(//PremiumDistributionRequest/Payment/ap:PaymentId)'&lt;/span&gt;)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-8685387830589084291?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/8685387830589084291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=8685387830589084291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8685387830589084291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8685387830589084291'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/05/sql-xml-element-contents-from-varchar.html' title='SQL XML Element contents from varchar column'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-1240262641326678024</id><published>2010-02-18T11:01:00.007+02:00</published><updated>2010-02-18T12:00:39.942+02:00</updated><title type='text'>Fitnesse - MyFirstTest</title><content type='html'>&lt;p&gt;Last night I ran through &lt;a href="http://blog.cornetdesign.com/2005/11/fitnesse-and-net-a-basic-tutorial/"&gt;a basic tutorial&lt;/a&gt; on Fitnesse and .net. It went a little something like this.&lt;/p&gt;
&lt;h3&gt;Download and run Fitnesse&lt;/h3&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/S30LEZyOHZI/AAAAAAAAAE4/xit9lJZ-18s/s1600-h/fitnesse-jar.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 79px; height: 74px;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/S30LEZyOHZI/AAAAAAAAAE4/xit9lJZ-18s/s320/fitnesse-jar.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439516095202336146" /&gt;&lt;/a&gt;&lt;p&gt;&lt;a href="http://fitnesse.org/FrontPage.FitNesseDevelopment.DownLoad"&gt;Download&lt;/a&gt;, double-click. And then...&lt;/p&gt;&lt;p&gt;Huh? I double clicked the jar file, got a question about enabling network comms, and nothing else happened.&lt;/p&gt;
&lt;p&gt;What had actually happened was some files were extracted and the server started running and listening for connections.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/S30MZqNU1UI/AAAAAAAAAFI/uWD1K9bWwFc/s1600-h/fitnesse-cmd.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 78px;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/S30MZqNU1UI/AAAAAAAAAFI/uWD1K9bWwFc/s400/fitnesse-cmd.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439517559899870530" /&gt;&lt;/a&gt;
&lt;p&gt;Best plan for getting started is to run it as above from the command line using &lt;code&gt;"[path to java bin]java.exe -jar fitnesse.jar&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Create a test page&lt;/h3&gt;
&lt;p&gt;The tutorial pointed to &lt;a href="http://www.fitnesse.org/FitNesse.DotNet.DotNetFitServer"&gt;FitNesse.DotNet.DotNetFitServer&lt;/a&gt;, which is an empty wiki page. Throwing caution to the wind, I bravely soldiered on.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/S30HxJaVJKI/AAAAAAAAAEo/0lhbnwpV3QA/s1600-h/ErrorsOccurred.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 84px; height: 133px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/S30HxJaVJKI/AAAAAAAAAEo/0lhbnwpV3QA/s320/ErrorsOccurred.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439512465854768290" /&gt;&lt;/a&gt;
&lt;p&gt;All looked fine until I clicked the test button and was presented with a nice red X in the upper right corner, clicking on which yielded the detail: &lt;code&gt;
java.io.IOException: Cannot run program "fit.FitServer": CreateProcess error=2, The system cannot find the file specified&lt;/code&gt;, which I was pretty much expecting, so off I went to find a suitable program.&lt;/p&gt;
&lt;p&gt;I downloaded both &lt;a href="http://www.syterra.com/FitSharp.html"&gt;FitSharp&lt;/a&gt; and &lt;a href="http://www.syterra.com/FitnesseDotNet.html"&gt;FitnesseDotNet&lt;/a&gt; because I couldn't tell which would be right for me. Updating the &lt;code&gt;TEST_RUNNER&lt;/code&gt; to the full path to the FitServer.exe from the FitnesseDotNet distribution did the trick (FitSharp is for slim testing and has a different &lt;code&gt;COMMAND_PATTERN&lt;/code&gt; and &lt;code&gt;TEST_RUNNER&lt;/CODE&gt;).&lt;/p&gt;
&lt;h3&gt;Create &amp; Hook fitnesse to the .net Class&lt;/h3&gt;
&lt;p&gt;Initially fitnesse couldn't find the type in any of the loaded assemblies. Removing the namespaces (as per a useful comment), got it to hook up, and I did a little "dance, or a jig".&lt;/p&gt;
&lt;h3&gt;Get to Green&lt;/h3&gt;
&lt;p&gt;Well, not quite green because one of the quotients in the table is incorrect. But the tests shows up this as an incorrect result.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/S30Kl-NFtDI/AAAAAAAAAEw/l9TwZY58bBk/s1600-h/MyFirstTest.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 239px;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/S30Kl-NFtDI/AAAAAAAAAEw/l9TwZY58bBk/s320/MyFirstTest.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5439515572402762802" /&gt;&lt;/a&gt;
&lt;p&gt;Yay.&lt;/p&gt;
&lt;p&gt;Next step is figuring out what fixture to use to get complex types into fitnesse.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-1240262641326678024?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/1240262641326678024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=1240262641326678024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/1240262641326678024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/1240262641326678024'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/02/fitnesse-myfirsttest.html' title='Fitnesse - MyFirstTest'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/S30LEZyOHZI/AAAAAAAAAE4/xit9lJZ-18s/s72-c/fitnesse-jar.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-1994298163304356375</id><published>2010-01-21T11:23:00.005+02:00</published><updated>2010-01-21T11:45:27.559+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dos'/><title type='text'>DOS Copy file aggregation</title><content type='html'>&lt;p&gt;Just learned something new about the DOS copy command from &lt;a href="http://www.howtogeek.com/howto/keyboard-ninja/keyboard-ninja-concatenate-multiple-text-files-in-windows/#comment-19300"&gt;this comment&lt;/a&gt; on a keyboard ninja article.&lt;/p&gt;
&lt;code&gt;copy /a *.txt aggregate.txt&lt;/code&gt;
&lt;p&gt;Will aggregate the contents of all the &lt;code&gt;.txt&lt;/code&gt; files into &lt;code&gt;aggregate.txt&lt;/code&gt;. This is useful to me for &lt;code&gt;.csv&lt;/code&gt; files.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/S1ggpLYWjwI/AAAAAAAAAEg/WlmFJ8HJTRI/s1600-h/copy.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 310px; height: 139px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/S1ggpLYWjwI/AAAAAAAAAEg/WlmFJ8HJTRI/s400/copy.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5429125242596790018" /&gt;&lt;/a&gt;
&lt;p style='text-align:center;'&gt;&lt;em&gt;&lt;code&gt;(to disambiguate: 1.txt contains "one one one" &amp;c.)&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So cool; not often I find out something new about DOS.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-1994298163304356375?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/1994298163304356375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=1994298163304356375' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/1994298163304356375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/1994298163304356375'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2010/01/dos-copy-file-aggregation.html' title='DOS Copy file aggregation'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/S1ggpLYWjwI/AAAAAAAAAEg/WlmFJ8HJTRI/s72-c/copy.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-3664710166951497208</id><published>2009-08-20T10:36:00.006+02:00</published><updated>2009-08-20T12:42:21.216+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sqlserver c#'/><title type='text'>Microsoft.SqlServer.Management.Smo Missing Backup</title><content type='html'>&lt;h2&gt;Or, how I learned to read the assembly name&lt;/h2&gt;
&lt;h3&gt;In which I include dll's&lt;/h3&gt;
I was trying out &lt;a href="http://www.geekpedia.com/tutorial180_Backup-and-restore-SQL-databases.html"&gt;this tutorial on Geekpedia&lt;/a&gt; and the references were invalid. I removed the two (&lt;code&gt;Microsoft.SqlServer.Smo&lt;/code&gt; and &lt;code&gt;Microsoft.SqlServer.ConnectionInfo&lt;/code&gt;: yes, the dll names are missing the &lt;code&gt;.Management&lt;/code&gt; part from the namespace they contain) and re-added them. Simple enough.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/So0ZRqab6jI/AAAAAAAAAEU/CNx75YKz1ss/s1600-h/Sdk.Sfc.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 105px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/So0ZRqab6jI/AAAAAAAAAEU/CNx75YKz1ss/s400/Sdk.Sfc.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5371977721756510770" /&gt;&lt;/a&gt;

Then there was an issue with the unreferenced &lt;code&gt;Microsoft.SqlServer.Management.Sdk.Sfc&lt;/code&gt;, after running &lt;a href="http://www.aghausman.net/dotnet/could-not-load-file-or-assembly-microsoftsqlservermanagementsdksfc.html"&gt;the installers&lt;/a&gt; (all just said repairing), I found the dll, but I'm not sure if it was there before. The dll in this case has the same name as the namespace, unlike the previous two dll's which are missing the &lt;code&gt;.Management&lt;/code&gt; portion, so I was looking in the wrong part of the list.


&lt;h3&gt;In which I question my sanity&lt;/h3&gt;
All was relatively sane up to this point, then I started to think I was crazy. The Backup class was missing from the namespace. I checked the documentation for &lt;code&gt;Microsoft.SqlServer.Management&lt;/code&gt; and sure enough, &lt;code&gt;Backup&lt;/code&gt; was there.

After turning to google for a while and reading all about people finding and GACing the dll, I headed to &lt;code&gt;%systemroot%/assembly&lt;/code&gt; to see what I had. It was at this point that I saw there was a dll &lt;code&gt;Microsoft.SqlServer.SmoExtended&lt;/code&gt;. Inquisitively, I added a reference to this dll. 

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/So0X7Q3YvAI/AAAAAAAAAEM/1VhgbzaWJZY/s1600-h/Microsoft.SqlServer.Management.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 385px; height: 155px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/So0X7Q3YvAI/AAAAAAAAAEM/1VhgbzaWJZY/s400/Microsoft.SqlServer.Management.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5371976237429865474" /&gt;&lt;/a&gt;

And, lo! the classes were found.

Looking at &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.backup.aspx"&gt;the documentation for the &lt;code&gt;Backup&lt;/code&gt; class&lt;/a&gt;, I now notice:
&lt;blockquote&gt;The &lt;b&gt;Backup&lt;/b&gt; object provides programmatic access to Microsoft SQL Server backup operations.
&lt;br/&gt;&lt;b&gt;Namespace:&lt;/b&gt; Microsoft.SqlServer.Management.Smo
&lt;br/&gt;&lt;b&gt;Assembly:&lt;/b&gt; Microsoft.SqlServer.SmoExtended (in microsoft.sqlserver.smoextended.dll)&lt;/blockquote&gt;
&lt;h3&gt;A curious discovery&lt;/h3&gt;
So, multiple dlls can add classes to the namespace. Who knew? Not me.

And, w.r.t. &lt;code&gt;Microsoft.SqlServer.Management.Smo&lt;/code&gt;, their structure must have changed somewhere between the dlls that Andrew Pociu (Geekpedia) was using (I'm assuming 9.x) and the 10.0 dlls.
&lt;h3&gt;Post-script: local help is outdated&lt;/h3&gt;
&lt;p&gt;While writing this post, I thought to check &lt;a href="ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/smo9mref/html/f0a63a06-ebfa-bb1e-c32c-0613f45118fa.htm"&gt;my local help&lt;/a&gt; where the documentation is out of date, so perhaps I have a valid excuse.
&lt;blockquote&gt;
The &lt;b&gt;Backup&lt;/b&gt; object provides programmatic access to Microsoft SQL Server backup operations. 
&lt;br/&gt;&lt;b&gt;Namespace:&lt;/b&gt; Microsoft.SqlServer.Management.Smo
&lt;br/&gt;&lt;b&gt;Assembly:&lt;/b&gt; Microsoft.SqlServer.Smo (in microsoft.sqlserver.smo.dll)
&lt;/blockquote&gt;
fin&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-3664710166951497208?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/3664710166951497208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=3664710166951497208' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3664710166951497208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3664710166951497208'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2009/08/microsoftsqlservermanagementsmo-missing.html' title='Microsoft.SqlServer.Management.Smo Missing Backup'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/So0ZRqab6jI/AAAAAAAAAEU/CNx75YKz1ss/s72-c/Sdk.Sfc.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-7564723817979863895</id><published>2009-05-26T09:50:00.008+02:00</published><updated>2009-05-27T11:02:51.063+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tfs'/><category scheme='http://www.blogger.com/atom/ns#' term='sharepoint'/><title type='text'>WSP in TFS: A few more parameters</title><content type='html'>&lt;p&gt;After my last post on &lt;a href="http://campey.blogspot.com/2009/05/building-wsp-in-tfs.html"&gt;building WSP in TFS&lt;/a&gt;, I was at a stage where I thought the WSP file was ready to go. It's recognised by &lt;a href="http://www.rarlab.com/"&gt;WinRAR&lt;/a&gt;, opening it up in there shows the expected dll's.&lt;/p&gt;
&lt;p&gt;But there was something missing...&lt;/p&gt;
&lt;h3&gt;feature.xml&lt;/h3&gt;
Attempting to deploy the WSP threw:
&lt;blockquote&gt;Failed to find the XML file at location '12\Template\Features\IL.SharePoint.Workflows\feature.xml'&lt;/blockquote&gt;
&lt;p&gt;This &lt;a href="http://technet.microsoft.com/en-us/library/cc263123.aspx"&gt;TechNet page on InstallFeature&lt;/a&gt; clears up the exact cause being a missing feature.xml. It also cleared up that the 'root' of the WSP is equivalent to &lt;code&gt;12\Template\Features\&lt;/code&gt; a location in the "12 hive".
&lt;p&gt;Opening up the WSP, sure enough there was no sign of feature.xml, so it was time to head back into &lt;code&gt;WSPbuilder.exe -help&lt;/code&gt; where I found...&lt;/p&gt;
&lt;h3&gt;-12path&lt;/h3&gt;
&lt;p&gt;The default for the 12path is the current directory, here again, since we're not running from the project directory, the current directory isn't much good, so I needed to set the 12 path.&lt;/p&gt;
&lt;p&gt;Setting the 12path to the location of the feature.xml got it included in the WSP, but the manifest.xml included it in the &lt;code&gt;RootFiles&lt;/code&gt; element. Based on our manually built WSP, we saw we needed it to be in the &lt;code&gt;FeatureManifests&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;After some searching I looked again at the &lt;a href="http://www.keutmann.dk/sharepointblog/wspbuilder/wspdemo.jpg"&gt;before build image&lt;/a&gt; on the WSPBuilder CodePlex site. Turns out this is rather useful once you know what you're looking at. There you'll see the path &lt;code&gt;WSPDemo/12/Template/FEATURES/WSPDemo/&lt;/code&gt;; after seeing that, it dawned on me that I had actually read something about "putting the contents of your 12 hive into the project folder" - so &lt;span style="font-style:italic;"&gt;that's&lt;/span&gt; what they meant.&lt;/p&gt;
&lt;p&gt;So finally the files were included in the WSP in the right location:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/Sh0BpaFzmEI/AAAAAAAAAEE/sdJ0colxAQk/s1600-h/WSPcontents.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 255px;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/Sh0BpaFzmEI/AAAAAAAAAEE/sdJ0colxAQk/s400/WSPcontents.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340426544021215298" /&gt;&lt;/a&gt;
&lt;h3&gt;-DeploymentTarget GAC&lt;/h3&gt;
Because of the way our solution is set up we need to target the GAC, we were getting:
&lt;blockquote&gt;&amp;lt;Assembly Location="IL.SharePoint.Workflows.dll" DeploymentTarget="WebApplication" /&amp;gt; 
&lt;/blockquote&gt;
in the &lt;code&gt;manifest.xml&lt;/code&gt;. Changing the &lt;code&gt;DeploymentTarget&lt;/code&gt; from the default of &lt;code&gt;Auto&lt;/code&gt; to &lt;code&gt;GAC&lt;/code&gt;yielded the required:
&lt;blockquote&gt;&amp;lt;Assembly Location="IL.SharePoint.Workflows.dll" DeploymentTarget="GlobalAssemblyCache" /&amp;gt;&lt;/blockquote&gt;
&lt;h3&gt;-BuildCAS False&lt;/h3&gt;
&lt;p&gt;The default for this is &lt;code&gt;True&lt;/code&gt;, with it on, the manifest file was spammed full of CAS information and trying to deploy gave the error:
&lt;blockquote&gt;The solution "IL.SharePoint.Workflows.wsp" needs to add Code Access Security policies. If you fully trust this solution, use the -allowCasPolicies parameter to deploy.&lt;/blockquote&gt;
True, using &lt;code&gt;-allowCasPolicies  &lt;/code&gt; did remove the error, but adding &lt;code&gt;-BuildCAS False&lt;/code&gt; cleaned up the manifest file and removed the need for this switch to &lt;code&gt;stsadm&lt;/code&gt;.
&lt;h3&gt;Revised WSPBuilder command line&lt;/h3&gt;
All this meant the following amended &lt;code&gt;Exec&lt;/code&gt; command in the tfsbuild.proj.
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Exec&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Command&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;quot;C:\Program Files\WSPTools\WSPBuilderExtensions\WSPBuilder&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -DeploymentTarget GAC &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -BuildCAS false &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -SolutionPath &amp;quot;$(OutDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -BinPath &amp;quot;$(OutDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -OutputPath &amp;quot;$(WspDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -12Path &amp;quot;$(OutDir)12&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -WSPName IL.SharePoint.Workflows.wsp&lt;/span&gt;'&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-7564723817979863895?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/7564723817979863895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=7564723817979863895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7564723817979863895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7564723817979863895'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2009/05/wsp-in-tfs-few-more-parameters.html' title='WSP in TFS: A few more parameters'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PyasagsZ3QA/Sh0BpaFzmEI/AAAAAAAAAEE/sdJ0colxAQk/s72-c/WSPcontents.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-5445048158617033602</id><published>2009-05-14T11:33:00.008+02:00</published><updated>2009-05-14T16:29:17.571+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sharepoint tfs'/><title type='text'>Building WSP in TFS</title><content type='html'>&lt;p&gt;We needed to build a Sharepoint WSP file in TFS as part of our continuous integration process. Already using &lt;a href="http://wspbuilder.codeplex.com/"&gt;WSPBuilder&lt;/a&gt; interactively we just needed to get it into the team build and copied to the staging location.&lt;/p&gt;

&lt;h3&gt;WSPBuilder&lt;/h3&gt;

&lt;p&gt;Brian Farnhill discusses the process of &lt;a href="http://pointstoshare.spaces.live.com/Blog/cns!AEC42F315B4528B0!3290.entry"&gt;building a WSP in TFS&lt;/a&gt; by first including it in the project file (&lt;a href="http://alex-tfs.blogspot.com/2009/01/tfs-build-and-wspbuilder.html"&gt;summary by Alex Degaston&lt;/a&gt;). This pointed me in the right direction, but I really just wanted to build the WSP in the team build after check-in.&lt;/p&gt;

&lt;p&gt;We just copied the basics from Brian's post, and hoped it would work, and amazingly, we had a WSP file. Frustratingly, the WSPBuilder will happily create a WSP file even if it finds nothing to put in it.&lt;/p&gt;

&lt;p&gt;After some experimenting on the command line, it turns out you need to specify both SolutionPath and BinPath to get WSPBuilder to build successfully, using the &lt;a href="http://www.woodwardweb.com/vsts/30_useful_team.html"&gt;team build property&lt;/a&gt; OutDir worked for this. Including the feature.xml and workflow.xml as content in the root of the project ensures they're in the output folder.&lt;/p&gt;

&lt;p&gt;The default name for the WSP is the folder name, so to override this, use WSPName.&lt;/p&gt;

&lt;h3&gt;File drop&lt;/h3&gt;

&lt;p&gt;The easiest way to get the files out was to override BeforeDropBuild and put them in the OutDir. I'm using xcopy for this as it's easier to test on the command line (also, using the copy task would require (I think) further nesting the copy operation because of the &lt;a href="http://manicprogrammer.com/cs/blogs/michaelruminer/archive/2008/02/23/teambuild-outdir-item-expansion-and-why-your-copy-task-gave-you-nothing.aspx"&gt;order of item expansion&lt;/a&gt;). They're then ready for the team build to perform the drop to the staging location.&lt;/p&gt;

&lt;h3&gt;Finally&lt;/h3&gt;

&lt;p&gt;All this boils down to this two liner added to the TFSBuild.proj:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Target&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Name&lt;/span&gt;&lt;span style="color: blue;"&gt; =&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt;BeforeDropBuild&lt;/span&gt;&amp;quot;&lt;span style="color: blue;"&gt; &amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;WspDir&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;$(SolutionRoot)\Code\IL.SharePoint.Workflows\DeploymentFiles&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;WspDir&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Exec&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Command&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;quot;C:\Program Files\WSPTools\WSPBuilderExtensions\WSPBuilder&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -SolutionPath &amp;quot;$(OutDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -BinPath &amp;quot;$(OutDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -OutputPath &amp;quot;$(WspDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -WSPName IL.SharePoint.Workflows.wsp&lt;/span&gt;'&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Exec&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;Command&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;xcopy /E /Y /I &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;$(WspDir)&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;$(OutDir)DeploymentFiles&amp;quot;&lt;/span&gt;'&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px; padding: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Target&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-5445048158617033602?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/5445048158617033602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=5445048158617033602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5445048158617033602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/5445048158617033602'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2009/05/building-wsp-in-tfs.html' title='Building WSP in TFS'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4455783844774486260</id><published>2009-05-12T12:24:00.003+02:00</published><updated>2009-05-14T16:38:51.545+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tfs'/><title type='text'>Incremental Get</title><content type='html'>&lt;p&gt;Trawling through Microsoft.TeamFoundation.Build I found the flag for IncrementalGet. Not getting full sources every time has cut 40 seconds out of every build. This is particularly useful when debugging a build script.&lt;/p&gt;

&lt;p&gt;Buck Hodges discusses &lt;a href="http://blogs.msdn.com/buckh/archive/2007/07/24/tfs-2008-some-properties-that-you-can-use-to-customize-your-build.aspx"&gt;IncrementalGet and IncrementalBuild&lt;/a&gt; and links to Martin Woodward's &lt;a href="http://www.woodwardweb.com/vsts/000374.html"&gt;30 Useful Team Build Properties&lt;/a&gt;. Not sure I'm ready for IncrementalBuild yet, I like having shiny new dll's.&lt;/p&gt;

&lt;p&gt;This is what I added to my root level PropertyGroup just before DropLocation:&lt;/p&gt;

&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green;"&gt; INCREMENTAL GET&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Setting this flag will set:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CleanCompilationOutputOnly: true&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; SkipInitializeWorkspace: true&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ForceGet: false&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; (Microsoft.TeamFoundation.Build Line:379)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;IncrementalGet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;IncrementalGet&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4455783844774486260?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4455783844774486260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4455783844774486260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4455783844774486260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4455783844774486260'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2009/05/incremental-get.html' title='Incremental Get'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-6226666236630755557</id><published>2009-04-03T12:02:00.002+02:00</published><updated>2009-04-03T12:06:22.123+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><title type='text'>Bloons Tower Defense III</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/SdXffYOkQII/AAAAAAAAAD0/9ozL1IJVDQ0/s1600-h/BloonsLastHard.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 187px; height: 176px;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/SdXffYOkQII/AAAAAAAAAD0/9ozL1IJVDQ0/s400/BloonsLastHard.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5320404264980594818" /&gt;&lt;/a&gt;
Yay, today I finished the last stage of &lt;a href="http://www.ninjakiwi.com/Games/Tower-Defense/Play/Bloons-Tower-Defense-3.html"&gt;Bloons Tower Denfense III&lt;/a&gt; on hard.

Hopefully this will cure the compulsion.

Oh look, &lt;a href="http://www.ninjakiwi.com/Games/Puzzle/Meeblings.html"&gt;meeblings&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-6226666236630755557?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/6226666236630755557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=6226666236630755557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6226666236630755557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6226666236630755557'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2009/04/bloons-tower-defense-iii.html' title='Bloons Tower Defense III'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/SdXffYOkQII/AAAAAAAAAD0/9ozL1IJVDQ0/s72-c/BloonsLastHard.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-3308372096277412511</id><published>2008-10-01T09:36:00.003+02:00</published><updated>2008-10-01T09:50:34.987+02:00</updated><title type='text'>No more cAPS LOCK</title><content type='html'>&lt;p&gt;The only time I hit the &lt;kbd&gt;Caps Lock&lt;/kbd&gt; key is by accident. Well, the only time I used to hit that key was by accident.&lt;/p&gt;
&lt;p&gt;After sitting down for a little think, I decided it would be good to remap the key to &lt;kbd&gt;Enter&lt;/kbd&gt;. With the help of US Netizen's &lt;a href="http://www.usnetizen.com/fix_capslock.php"&gt;Fix Caps Lock&lt;/a&gt; page, I was well on my way.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/SOMqIdk1mHI/AAAAAAAAAC8/y72vDaJO3sg/s1600-h/remap.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/SOMqIdk1mHI/AAAAAAAAAC8/y72vDaJO3sg/s400/remap.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5252087915310585970" /&gt;&lt;/a&gt;
&lt;p&gt;Adding the above key to &lt;code&gt;HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout&lt;/code&gt; and rebooting gave me another &lt;code&gt;Enter&lt;/code&gt; key. It adds a certain symmetry to the keyboard.&lt;/p&gt;
&lt;p&gt;And it still gives me happy jollies every time I hit it on purpose. Synapse-creation ahoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-3308372096277412511?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/3308372096277412511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=3308372096277412511' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3308372096277412511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3308372096277412511'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2008/10/no-more-caps-lock.html' title='No more cAPS LOCK'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PyasagsZ3QA/SOMqIdk1mHI/AAAAAAAAAC8/y72vDaJO3sg/s72-c/remap.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-6679099183131420325</id><published>2008-09-02T17:34:00.003+02:00</published><updated>2008-09-02T17:45:05.684+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xgame'/><title type='text'>xgame: An update</title><content type='html'>I've done very little poking around on gravitas in the last year, my SVN repo only saw commits in September last year and March.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/SL1d7EvqQuI/AAAAAAAAAC0/HX6p5tMwwj0/s1600-h/UFO_dxBall.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/SL1d7EvqQuI/AAAAAAAAAC0/HX6p5tMwwj0/s400/UFO_dxBall.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5241448810796434146" /&gt;&lt;/a&gt;
Recent changes:
&lt;ul&gt;
&lt;li&gt;Physics works well enough to set up orbits.&lt;/li&gt;
&lt;li&gt;New models. (for the observant, the red planet is the ball from the dx samples)&lt;/li&gt;
&lt;/ul&gt;
&lt;a href="http://blogs.msdn.com/xna/archive/2007/12/13/xna-game-studio-2-0-released.aspx"&gt;XNA 2.0&lt;/a&gt; might be part of the reason for stalling, I've been pondering the move to there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-6679099183131420325?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/6679099183131420325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=6679099183131420325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6679099183131420325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6679099183131420325'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2008/09/xgame-update.html' title='xgame: An update'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PyasagsZ3QA/SL1d7EvqQuI/AAAAAAAAAC0/HX6p5tMwwj0/s72-c/UFO_dxBall.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-2273050799833124038</id><published>2008-08-18T16:46:00.002+02:00</published><updated>2008-08-18T16:58:49.409+02:00</updated><title type='text'>XMPP Message Update: Sending</title><content type='html'>&lt;p&gt;I've gotten off the starting block with implementing the &lt;a href="http://titan.informationlogistics.co.za/~campey/JEPsx/Message%20Update%20JEP.html"&gt;message update JEP&lt;/a&gt;. The implementation has matured in the 2 years (!) since I drafted the JEP and it's become a lot simpler.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/SKmLmTcsqtI/AAAAAAAAACs/lUTFnIRxNkw/s1600-h/Message_Update_Transmit.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/SKmLmTcsqtI/AAAAAAAAACs/lUTFnIRxNkw/s400/Message_Update_Transmit.png" alt="" id="BLOGGER_PHOTO_ID_5235869531966843602" border="0" /&gt;&lt;/a&gt;
&lt;p&gt;What I've done so far: use gajim's sent message history to select a message, then insert the replace element when retransmitted. The replace element is all that we need to correct typos.&lt;/p&gt;
&lt;p&gt;The image also illustrates the elegant degrading as neither client supports the protocol. Yet.&lt;/p&gt;
&lt;p&gt;Gajim tx done. Gajim rx and Psi tx/rx to come. And a shiny new &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;X&lt;/span&gt;&lt;/span&gt;EP&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-2273050799833124038?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/2273050799833124038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=2273050799833124038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/2273050799833124038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/2273050799833124038'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2008/08/xmpp-message-update-sending.html' title='XMPP Message Update: Sending'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/SKmLmTcsqtI/AAAAAAAAACs/lUTFnIRxNkw/s72-c/Message_Update_Transmit.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-415587176160249944</id><published>2007-09-05T21:24:00.000+02:00</published><updated>2007-09-05T21:34:38.902+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xgame'/><title type='text'>xgame: Hellish Heli</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/Rt8C4MwEGJI/AAAAAAAAACE/AzBwjUlIN70/s1600-h/heli.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/Rt8C4MwEGJI/AAAAAAAAACE/AzBwjUlIN70/s320/heli.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5106803666980182162" /&gt;&lt;/a&gt;&lt;p&gt;So I dug up the ol' gravitas solution and decided it was time to load a mesh in there. &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx"&gt;Coding4Fun&lt;/a&gt; again proved helpful.  Unlike the very uninformative error messages from DirectX. With some playing about, I managed to get the sample heli.x to load and render in stark white.&lt;/p&gt;&lt;p&gt;Then I had to turn on &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx"&gt;the lights&lt;/a&gt;. (&lt;code&gt;device.RenderState.Lighting  = true; device.RenderState.Ambient = Color.White;&lt;/code&gt;)&lt;/p&gt;&lt;p&gt;For some reason my point list is now ignoring its colours and using the last one that heli did. Sheep.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-415587176160249944?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/415587176160249944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=415587176160249944' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/415587176160249944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/415587176160249944'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/09/xgame-hellish-heli.html' title='xgame: Hellish Heli'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PyasagsZ3QA/Rt8C4MwEGJI/AAAAAAAAACE/AzBwjUlIN70/s72-c/heli.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-867068207882253521</id><published>2007-05-14T22:15:00.000+02:00</published><updated>2007-05-14T22:23:09.156+02:00</updated><title type='text'>picturesofwalls.com</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/RkjDjicTqKI/AAAAAAAAAB4/Pi7PG6AJXaY/s1600-h/048_thisisart.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/RkjDjicTqKI/AAAAAAAAAB4/Pi7PG6AJXaY/s320/048_thisisart.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5064512796286494882" /&gt;&lt;/a&gt;Title says it all. &lt;a href="http://www.picturesofwalls.com/"&gt;Pictures of walls&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Man some of these are funny.&lt;br /&gt;&lt;br /&gt;Great content, amusing presentation, and occasional irony.  Nothing quite like the venting of profound, repressed, anonymous vandals.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-867068207882253521?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/867068207882253521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=867068207882253521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/867068207882253521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/867068207882253521'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/picturesofwallscom.html' title='picturesofwalls.com'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PyasagsZ3QA/RkjDjicTqKI/AAAAAAAAAB4/Pi7PG6AJXaY/s72-c/048_thisisart.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4193171531259566089</id><published>2007-05-08T22:47:00.000+02:00</published><updated>2007-05-09T15:00:12.981+02:00</updated><title type='text'>TeamPlain Opensearch</title><content type='html'>&lt;p&gt;&lt;a href="http://www.devbiz.com/teamplain/webaccess/default.aspx"&gt;TeamPlain&lt;/a&gt; has a goto work-item search that opens up workitems, oddly enough.  I wanted to use the Firefox search box to fire this off.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Using the guide: &lt;a href="http://developer.mozilla.org/en/docs/Creating_OpenSearch_plugins_for_Firefox"&gt;Creating OpenSearch plug-ins for Firefox&lt;/a&gt;, I started putting together an XML OpenSearch description in &lt;a href="http://www.notepad.org/"&gt;notepad&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Needing an icon, I &lt;a href="http://www.gimp.org/"&gt;Gimp&lt;/a&gt;ed out the logo from the TeamPlain site, took it past the&lt;a href="http://software.hixie.ch/utilities/cgi/data/data"&gt; data: URI kitchen&lt;/a&gt; and popped it in.&lt;br /&gt;&lt;a href="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%06%00%00%00%1F%F3%FFa%00%00%00%06bKGD%00%FF%00%FF%00%FF%A0%BD%A7%93%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%07tIME%07%D7%05%08%14%0D(U%8F%FC%B3%00%00%00%1DtEXtComment%00Created%20with%20The%20GIMP%EFd%25n%00%00%03%D9IDATx%DA%25%CD%D9SUu%1C%00%F0%EFo9%F7%2C%F7%C0%85%CBv7%B8%C8%A6%80%2C%CA%92%2CS%86%25%C94%9A%19%92%8D%CD%80a5M%0F-%D34%95V%0F%3Dd%F1%D0%83H%93%83%93%E2LS4c6%26%88T6%23%13h%0B(%16b%5C%20%05%94%ED%02%F7r%B7s~%BF_%0F%7D%FE%81%0F%02E%D5%B1E%00'%08%B0%10%80%88%80%C7%1F%DD%EB%AA%DB%B5%DB%93%E6pj%CB%8B%F3%A1%BE%8B%DF%DF%BD%DCsn%16!%0E%00%18%B0%84%20*%24%C0FD%60%20%00%1C%10%00%07%E0%04%030%02%C9%DE%7C%C7%E6%ED%0Du%17%2C%B1%AA%EC%EA%9D%B5vO%AE%8B%23%0A%18K%C0%23B0%03%83%14%8D%82D9%A2%98%0B%E0%F0%FF%CE1%80%10%1CVW%FC%B1%D3%96%07%D2%A52%FB%86%85%D1%C1%F5%B8%15%7F%9F%C4%23%20%04%05BM%10%94%80%A1Y%81%98%01%81%85%10%08%13%86%B9%82%00%9B%02%803%B9%B5%B9%B9%ACQM%A9%8E%9FYZmN%CF%F7%B6%B6%B4%94%9A%26%969%05%00L%11%B0(%81p%08%0BF%10y%EE%C57%F2%DF%7C%FB%C3%B2%D9%09%9Fp%3B%5Cq%C7%DA%DA%AB%AA%B7%D5%BC%EE%95Tg%AB%3D%DB%91%A7%258%DD%8E%B4%92-%E5%E5%F7%EENLE%5C%9E%8C%C4%8F%DANV%A4o%C8%B3%5C%BF%FA%E3%02%EA%1E%B8sTNZ4%03%E1%2F%A1%D8%F1~F%92%EEj%00%60%BE_~%EA%BB22%3CL%0B%0A%0B%CD%9D%F5%0D%B5%80h%C1z%C4%E8%1D%EF%B8%F5%3B%2F%B3%A7%80%03kO%D6%E6%B5Q%87%CB%93%B3%E4%AC%1B%84%05%FF%E6%A9%F9%F2%A4%E4%B8%D6%FBG%8E%BC%F5i%E7%E7'%261B~!%C0%F6L%D3%81%C1%F6%8ES%EF%B2%81%90%BF%B8%D3%A5%FC%FC%F1P0k%AC!gc%CD%0E%1By%A8~oE2)u%AF-%07%D5m%B9G%BD%91%08%BB%FAJ%EB%C1%CB%20%C3%2C2D%0Cd%12%18%1B%BD%11j9%F4%92%23%C1%9DP%F3%CF%AF%E3AyO%0ALX%E7%B8%CF7%ED%03%90%B5%CA%AC%D2%CA%3D%DF%5C%F9%F3%BD%7F%D7%C4%9D%1B%BE%D9N%A4%D14%9A%A4%E9TUtl%B3%EAD%C5%C9%BF%FD5%D95%13%10%93%3F%0C%FD%FD%C1%D6G%1E%DB%07%B2V%89%AC%9A%07%40Uu%D0%15%1BM%F3n%19_b%E7%E7%82%FCRaEE.%8E%D7uK%A2%A4%D3DU%CF-)%CA%9CY%89%5C%9C%F4%B3%9E%B8%EC%82%ADT%93%E3I%7C%9CUN%94%AD%18c%01%00%88%99k%8B%81%A8%C9V%98%40%1B%BB%CE~%DB%A2%11)%C9%08%09%2B%8B1%FB%99%D3_%1F%C2T.%8A%9A%2C%14%98%9D%0A%80baB%A5%60Z%40P%C1%11%60%99%83%96%98%8A%23%E1u%D5o%C2P%AA3%E3%E9%DBS%0F%AA%40%B0%01%82q9C%96%AC%95%D5%C0%CD%18%03%C9%EE%CE%40%C1%A5i%60%0C%012%10%60%C4%05%08Ch%C7%BF%F8j%87v%EB%C0%9A%D1%E3%8C%AE%AC%CF%F7F%85%E4%8E%81%B2%3F%CC-%D9%A1%B5%60%BF%F1%7C%D1%D8Zs%C5%FD%E3%1D%5D%DB%8D(X%11cB%20%02%94c%04%0DM%AFffm*-w%8F%8F%E83%C4p%AD%07%E6%A6%8E%7D%D2%FE%D9%ED%9B%7F%90%CC%EC%3C%F3%9D%C3%87%3D9%A1%A5%82I%93%AA%D2%A6%12c%FF%0B%AF%8Dv%9F91%22%A10%00%B6*%3A(%AA%B3%A0%B6~%DFw%FD%E7%DB%AE%0F%F7%9Fz%E2%E0%CB%CF%12%C5%EA%25%AAd%C3%0Au%3D%BC%BB%E9%A9k%17zO%9E%3B%DB%DDQ%B9%AB%B1%11%5B%157I%B1Y%B1C%D6%10h%AA%8E%25%01%9CqE%92l%C5i%E9Y%A9%B3%D3%13%D7%90%14%9A%87%00%07%A1%08%101%9C%E8%CE-%A9%9E%BF%E7%5B6%C3%91aI5BQ*%03%8D%86%C5%7Fs%3B%AAS%D9I.%22%00%00%00%00IEND%AEB%60%82"&gt;&lt;br /&gt;&lt;code&gt;data:image/png,%89PNG%0D%...&lt;/code&gt;&lt;/a&gt;&lt;br /&gt;Okay, so it's fugly, but it doesn't look too bad on the search bar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;A glance at the &lt;a href="http://www.opensearch.org/Specifications/OpenSearch/1.1/Draft_3#OpenSearch_1.1_parameters"&gt;OpenSearch Specification&lt;/a&gt; provided final tips when deciding what data should go where.  Now I had an XML file and needed someway to consume it&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I tried &lt;a href="http://developer.mozilla.org/en/docs/Adding_search_engines_from_web_pages"&gt;installing the OpenSearch plug-in&lt;/a&gt;.  I used the Error Console in Firefox, running the command &lt;code&gt;window.external.AddSearchProvider(engineURL);&lt;/code&gt; using a &lt;code&gt;file:///&lt;/code&gt; URI for the engineURL, but kept getting a URL formatting error.  &lt;br /&gt;&lt;code&gt;&lt;pre&gt;Error: Invalid argument passed to &lt;br /&gt;  window.sidebar.addSearchEngine: &lt;br /&gt;  Unsupported search engine&lt;br /&gt;Source File: file:///C:/Program%20Files/Gran%20Paradiso&lt;br /&gt;  /components/nsSidebar.js&lt;br /&gt;Line: 114&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;Initially I thought this was due to the URL in the XML definition file, so I hacked around with that for a bit, then when that yielded no fruit, I extended the error message in the mentioned .js to include the invalid URL. This was the URL to the XML doc, not the search URL inside the XML. Turns out the URL check in the .js that was throwing the exception was only regexing &lt;code&gt;https?|ftp&lt;/code&gt;, so needed a &lt;code&gt;|file&lt;/code&gt; appended.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now that Firefox was playing nicely with the XML, it was happy to load it up and prompt me to install it.&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/RkDt-ScTqII/AAAAAAAAABo/Zm5L4vCDle4/s1600-h/openSearch.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/RkDt-ScTqII/AAAAAAAAABo/Zm5L4vCDle4/s320/openSearch.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5062307635522676866" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;And it worked!&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/RkDuTCcTqJI/AAAAAAAAABw/TQ1ooqiMP0o/s1600-h/SearchBox.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/RkDuTCcTqJI/AAAAAAAAABw/TQ1ooqiMP0o/s320/SearchBox.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5062307992004962450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Final code: (adjust search URL to your liking)&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;OpenSearchDescription xmlns=&amp;quot;http://a9.com/-/spec/opensearch/1.1/&amp;quot;&lt;br /&gt;                       xmlns:moz=&amp;quot;http://www.mozilla.org/2006/browser/search/&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;ShortName&amp;gt;TeamPlain Item&amp;lt;/ShortName&amp;gt;&lt;br /&gt;&amp;lt;Description&amp;gt;Load items from local TeamPlain&amp;lt;/Description&amp;gt;&lt;br /&gt;&amp;lt;Image width=&amp;quot;16&amp;quot;height=&amp;quot;16&amp;quot;&amp;gt;&lt;br /&gt;data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%06%00%00%00%1F%F3%FFa%00%00%00%06bKGD%00%FF%00%FF%00%FF%A0%BD%A7%93%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%07tIME%07%D7%05%08%14%0D(U%8F%FC%B3%00%00%00%1DtEXtComment%00Created%20with%20The%20GIMP%EFd%25n%00%00%03%D9IDATx%DA%25%CD%D9SUu%1C%00%F0%EFo9%F7%2C%F7%C0%85%CBv7%B8%C8%A6%80%2C%CA%92%2CS%86%25%C94%9A%19%92%8D%CD%80a5M%0F-%D34%95V%0F%3Dd%F1%D0%83H%93%83%93%E2LS4c6%26%88T6%23%13h%0B(%16b%5C%20%05%94%ED%02%F7r%B7s~%BF_%0F%7D%FE%81%0F%02E%D5%B1E%00'%08%B0%10%80%88%80%C7%1F%DD%EB%AA%DB%B5%DB%93%E6pj%CB%8B%F3%A1%BE%8B%DF%DF%BD%DCsn%16!%0E%00%18%B0%84%20*%24%C0FD%60%20%00%1C%10%00%07%E0%04%030%02%C9%DE%7C%C7%E6%ED%0Du%17%2C%B1%AA%EC%EA%9D%B5vO%AE%8B%23%0A%18K%C0%23B0%03%83%14%8D%82D9%A2%98%0B%E0%F0%FF%CE1%80%10%1CVW%FC%B1%D3%96%07%D2%A52%FB%86%85%D1%C1%F5%B8%15%7F%9F%C4%23%20%04%05BM%10%94%80%A1Y%81%98%01%81%85%10%08%13%86%B9%82%00%9B%02%803%B9%B5%B9%B9%ACQM%A9%8E%9FYZmN%CF%F7%B6%B6%B4%94%9A%26%969%05%00L%11%B0(%81p%08%0BF%10y%EE%C57%F2%DF%7C%FB%C3%B2%D9%09%9Fp%3B%5Cq%C7%DA%DA%AB%AA%B7%D5%BC%EE%95Tg%AB%3D%DB%91%A7%258%DD%8E%B4%92-%E5%E5%F7%EENLE%5C%9E%8C%C4%8F%DANV%A4o%C8%B3%5C%BF%FA%E3%02%EA%1E%B8sTNZ4%03%E1%2F%A1%D8%F1~F%92%EEj%00%60%BE_~%EA%BB22%3CL%0B%0A%0B%CD%9D%F5%0D%B5%80h%C1z%C4%E8%1D%EF%B8%F5%3B%2F%B3%A7%80%03kO%D6%E6%B5Q%87%CB%93%B3%E4%AC%1B%84%05%FF%E6%A9%F9%F2%A4%E4%B8%D6%FBG%8E%BC%F5i%E7%E7'%261B~!%C0%F6L%D3%81%C1%F6%8ES%EF%B2%81%90%BF%B8%D3%A5%FC%FC%F1P0k%AC!gc%CD%0E%1By%A8~oE2)u%AF-%07%D5m%B9G%BD%91%08%BB%FAJ%EB%C1%CB%20%C3%2C2D%0Cd%12%18%1B%BD%11j9%F4%92%23%C1%9DP%F3%CF%AF%E3AyO%0ALX%E7%B8%CF7%ED%03%90%B5%CA%AC%D2%CA%3D%DF%5C%F9%F3%BD%7F%D7%C4%9D%1B%BE%D9N%A4%D14%9A%A4%E9TUtl%B3%EAD%C5%C9%BF%FD5%D95%13%10%93%3F%0C%FD%FD%C1%D6G%1E%DB%07%B2V%89%AC%9A%07%40Uu%D0%15%1BM%F3n%19_b%E7%E7%82%FCRaEE.%8E%D7uK%A2%A4%D3DU%CF-)%CA%9CY%89%5C%9C%F4%B3%9E%B8%EC%82%ADT%93%E3I%7C%9CUN%94%AD%18c%01%00%88%99k%8B%81%A8%C9V%98%40%1B%BB%CE~%DB%A2%11)%C9%08%09%2B%8B1%FB%99%D3_%1F%C2T.%8A%9A%2C%14%98%9D%0A%80baB%A5%60Z%40P%C1%11%60%99%83%96%98%8A%23%E1u%D5o%C2P%AA3%E3%E9%DBS%0F%AA%40%B0%01%82q9C%96%AC%95%D5%C0%CD%18%03%C9%EE%CE%40%C1%A5i%60%0C%012%10%60%C4%05%08Ch%C7%BF%F8j%87v%EB%C0%9A%D1%E3%8C%AE%AC%CF%F7F%85%E4%8E%81%B2%3F%CC-%D9%A1%B5%60%BF%F1%7C%D1%D8Zs%C5%FD%E3%1D%5D%DB%8D(X%11cB%20%02%94c%04%0DM%AFffm*-w%8F%8F%E83%C4p%AD%07%E6%A6%8E%7D%D2%FE%D9%ED%9B%7F%90%CC%EC%3C%F3%9D%C3%87%3D9%A1%A5%82I%93%AA%D2%A6%12c%FF%0B%AF%8Dv%9F91%22%A10%00%B6*%3A(%AA%B3%A0%B6~%DFw%FD%E7%DB%AE%0F%F7%9Fz%E2%E0%CB%CF%12%C5%EA%25%AAd%C3%0Au%3D%BC%BB%E9%A9k%17zO%9E%3B%DB%DDQ%B9%AB%B1%11%5B%157I%B1Y%B1C%D6%10h%AA%8E%25%01%9CqE%92l%C5i%E9Y%A9%B3%D3%13%D7%90%14%9A%87%00%07%A1%08%101%9C%E8%CE-%A9%9E%BF%E7%5B6%C3%91aI5BQ*%03%8D%86%C5%7Fs%3B%AAS%D9I.%22%00%00%00%00IEND%AEB%60%82&lt;br /&gt;&amp;lt;/Image&amp;gt;&lt;br /&gt;&amp;lt;InputEncoding&amp;gt;UTF-8&amp;lt;/InputEncoding&amp;gt;&lt;br /&gt;&amp;lt;Url type=&amp;quot;text/html&amp;quot; method=&amp;quot;GET&amp;quot;&lt;br /&gt;template=&amp;quot;http://05rnb-dev02:8090/workitem.aspx?id={searchTerms}&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;moz:SearchForm&amp;gt;searchFormURL&amp;lt;/moz:SearchForm&amp;gt;&lt;br /&gt;&amp;lt;/OpenSearchDescription&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4193171531259566089?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4193171531259566089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4193171531259566089' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4193171531259566089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4193171531259566089'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/teamplain-opensearch.html' title='TeamPlain Opensearch'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/RkDt-ScTqII/AAAAAAAAABo/Zm5L4vCDle4/s72-c/openSearch.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4827134277881881345</id><published>2007-05-03T15:24:00.000+02:00</published><updated>2007-05-03T15:34:29.860+02:00</updated><title type='text'>hp nx9420: Screen broken &amp; fixed!</title><content type='html'>So my screen went on the blink;  more like the scramble.  It was very upsetting, and it carried on like this for a few weeks.  I used an external monitor and sometimes the regular screen would work.  It was very unpredictable and would break without any cause, which frustrated the hell out of me.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/Rjnj-CcTqFI/AAAAAAAAABQ/b140zTOVSvA/s1600-h/nx9420_broken.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/Rjnj-CcTqFI/AAAAAAAAABQ/b140zTOVSvA/s320/nx9420_broken.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5060326311274457170" /&gt;&lt;/a&gt;&lt;br /&gt;Eventually while sitting in a friend's loungue I decided I really just had to see my screen.  So I grappled with her rather useless screwdrivers and took out the retaining screws for the keyboard.  After this was done I flipped the keyboard open, gave the internal screen connector a poke and turned it on.  &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/RjnkfCcTqGI/AAAAAAAAABY/ZSay5553tHc/s1600-h/nx9420_fixed.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/RjnkfCcTqGI/AAAAAAAAABY/ZSay5553tHc/s320/nx9420_fixed.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5060326878210140258" /&gt;&lt;/a&gt;&lt;br /&gt;And it worked.  Just like that.  And it's been working ever since.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4827134277881881345?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4827134277881881345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4827134277881881345' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4827134277881881345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4827134277881881345'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/hp-nx9420-screen-broken-fixed.html' title='hp nx9420: Screen broken &amp; fixed!'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/Rjnj-CcTqFI/AAAAAAAAABQ/b140zTOVSvA/s72-c/nx9420_broken.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-2343381865376165798</id><published>2007-05-03T15:11:00.000+02:00</published><updated>2007-05-03T22:25:04.298+02:00</updated><title type='text'>My Coke Fest: Hoobastank</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/RjngGycTqEI/AAAAAAAAABI/TjY2fedgojk/s1600-h/hoobastank.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/RjngGycTqEI/AAAAAAAAABI/TjY2fedgojk/s320/hoobastank.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5060322063551801410" /&gt;&lt;/a&gt;So, I went to the 'My Coke Fest' in Joburg.  It was pretty cool.  &lt;a href="http://www.hoobastank.com"&gt;Hoobastank&lt;/a&gt; rocked ;) their lead singer looked like he couldn't have been more than 20; turns out the whole band is over 30 -- there's hope for us yet.&lt;br /&gt;&lt;br /&gt;The picture (left) is of Hoobastank, with their lead singer standing on his box -- he was so tiny.  Apparently he's Incubus' brother, which is kinda cool.  They played some Bon Jovi and AC-DC to warm the crowd up for their no. 1 track, "The Reason".  It was unexpected to hear an international act covering, but they pulled it off with style.  Definitely the high-point of the 12-hour concert for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-2343381865376165798?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/2343381865376165798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=2343381865376165798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/2343381865376165798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/2343381865376165798'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/my-coke-fest-hoobastank.html' title='My Coke Fest: Hoobastank'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PyasagsZ3QA/RjngGycTqEI/AAAAAAAAABI/TjY2fedgojk/s72-c/hoobastank.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-7095546869452718593</id><published>2007-05-03T11:56:00.000+02:00</published><updated>2007-05-09T15:06:52.948+02:00</updated><title type='text'>Rocket Commander Tutorial Videos</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://msdn.microsoft.com/coding4fun/images/gamedev/rocketcmd/rocketcmd_0.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://msdn.microsoft.com/coding4fun/images/gamedev/rocketcmd/rocketcmd_0.jpg" border="0" alt="" /&gt;&lt;/a&gt;Not only is &lt;a href="http://www.rocketcommander.com/"&gt;Rocket Commander&lt;/a&gt; a pretty cool looking (but rather boring) MDX game with publicly available source, it turns out they've done a series of 10 30-minute &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/997852.aspx"&gt;video tutorials&lt;/a&gt; on the making of the game.

Sweet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-7095546869452718593?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/7095546869452718593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=7095546869452718593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7095546869452718593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/7095546869452718593'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/rocket-commander-tutorial-videos.html' title='Rocket Commander Tutorial Videos'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-8603787747749573301</id><published>2007-05-02T19:29:00.000+02:00</published><updated>2007-05-02T19:48:13.140+02:00</updated><title type='text'>xgame: Three-Dee space craft</title><content type='html'>So, I wanted to add substance to my craft.  This was quite easy.  I rearranged the points in the VertexBuffer into a list describing a triangle fan and fiddled to get that to work.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;pointList_VB = new VertexBuffer(typeof(CustomVertex.PositionColored),&lt;br /&gt;                     12, device,&lt;br /&gt;                     Usage.Dynamic | Usage.WriteOnly,&lt;br /&gt;                     CustomVertex.PositionColored.Format,&lt;br /&gt;                     Pool.Default);&lt;br /&gt;&lt;br /&gt;CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[12];&lt;br /&gt;&lt;br /&gt;// Triangle #1&lt;br /&gt;&lt;br /&gt;verts[0].Position = new Vector3(0.0f, 0.5f, 0.0f);&lt;br /&gt;verts[0].Color = Color.Blue.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[1].Position = new Vector3(0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[1].Color = Color.Green.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[2].Position = new Vector3(0.0f, 0.0f, 0.2f);&lt;br /&gt;verts[2].Color = Color.Orange.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[3].Position = new Vector3(-0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[3].Color = Color.Red.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[4].Position = new Vector3(0.0f, 0.0f, -0.2f);&lt;br /&gt;verts[4].Color = Color.Yellow.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[5].Position = new Vector3(0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[5].Color = Color.Green.ToArgb();&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Yawn. Then I appended some points to that list for a triangle list to close off the object.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;verts[6].Position = new Vector3(-0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[6].Color = Color.Red.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[7].Position = new Vector3(0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[7].Color = Color.Green.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[8].Position = new Vector3(0.0f, 0.0f, -0.2f);&lt;br /&gt;verts[8].Color = Color.Yellow.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[9].Position = new Vector3(-0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[9].Color = Color.Red.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[10].Position = new Vector3(0.5f, -0.2f, 0.0f);&lt;br /&gt;verts[10].Color = Color.Green.ToArgb();&lt;br /&gt;&lt;br /&gt;verts[11].Position = new Vector3(0.0f, 0.0f, 0.2f);&lt;br /&gt;verts[11].Color = Color.Orange.ToArgb();&lt;br /&gt;&lt;br /&gt;pointList_VB.SetData(verts, 0, LockFlags.None);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And then drawing it with indexed calls to my VB stream as follows.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;d3dDevice.SetStreamSource(0, pointList_VB, 0);&lt;br /&gt;d3dDevice.DrawPrimitives(PrimitiveType.PointList, 0, 7);&lt;br /&gt;d3dDevice.Transform.World = Matrix.Multiply(&lt;br /&gt;    Matrix.RotationYawPitchRoll(Geometry.DegreeToRadian(p1.Rotation.X), Geometry.DegreeToRadian(p1.Rotation.Y), Geometry.DegreeToRadian(p1.Rotation.Z)),&lt;br /&gt;    Matrix.Translation(p1.Position.X, p1.Position.Y, 20.0f)&lt;br /&gt;    );&lt;br /&gt;d3dDevice.DrawPrimitives(PrimitiveType.TriangleFan, 0, 5);&lt;br /&gt;d3dDevice.DrawPrimitives(PrimitiveType.TriangleList, 6, 11);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Drawing it revealed to me that I'd got up &amp; down confused on the y-rotation.. so after fixing that it was all solid.&lt;br /&gt;&lt;br /&gt;And it looks something like this. (from a few viewpoints)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PyasagsZ3QA/RjjOqCcTqDI/AAAAAAAAABA/EEfdNoNkBOg/s1600-h/threeD.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PyasagsZ3QA/RjjOqCcTqDI/AAAAAAAAABA/EEfdNoNkBOg/s320/threeD.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5060021402956179506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Really has to be seen in motion for full effect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-8603787747749573301?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/8603787747749573301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=8603787747749573301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8603787747749573301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8603787747749573301'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/xgame-three-dee-space-craft.html' title='xgame: Three-Dee space craft'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PyasagsZ3QA/RjjOqCcTqDI/AAAAAAAAABA/EEfdNoNkBOg/s72-c/threeD.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-4191628715453530282</id><published>2007-05-02T12:37:00.001+02:00</published><updated>2007-05-02T19:29:22.499+02:00</updated><title type='text'>Player variables into player object</title><content type='html'>So, I had collected a lovely bunch of variables to track the position of the craft, looking something like this: (gotta love having your dev history in an SVN repo)&lt;br /&gt;&lt;pre&gt;&lt;code&gt;        private Vector3 p1rot;&lt;br /&gt;        private Vector3 p1rotInput;&lt;br /&gt;        private float p1rotForce;&lt;br /&gt;        public Vector3 Player1Rotation&lt;br /&gt;        {&lt;br /&gt;            get { return p1rot; }&lt;br /&gt;            set { p1rot = value; }&lt;br /&gt;        }&lt;br /&gt;        private Vector2 p1;&lt;br /&gt;        public Vector2 Player1Location&lt;br /&gt;        {&lt;br /&gt;            get { return p1; }&lt;br /&gt;            set { p1 = value; }&lt;br /&gt;        }&lt;br /&gt;        private Vector2 p1force;&lt;br /&gt;        private Vector2 p1spring;&lt;br /&gt;        private Vector2 p1grav;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;And the time had come to move it out into an object. Which ended up looking like this: &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Player&lt;br /&gt;{&lt;br /&gt; private Vector2 _position;&lt;br /&gt; private Vector2 _force;&lt;br /&gt; private Vector3 _rotation;&lt;br /&gt; private Vector3 _rotationInput;&lt;br /&gt; private float _thrust;&lt;br /&gt; private float _rotationForce;&lt;br /&gt;&lt;br /&gt; public Vector2 Position&lt;br /&gt; {&lt;br /&gt;  get { return _position; }&lt;br /&gt;  set { _position = value; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;.. blah blah properties.  Thankfully we can use CTRL-R,E in Visual Studio to make a private variable into a public property; no mess, no fuss.  There was also dome debate as to where to put the public properties w.r.t. their privates, I went with Turner and used the C++ style approach.&lt;br /&gt;&lt;br /&gt;And I even gave the object its very own method to update it's internals.  Lucky thing.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt; public void HandleInput(float dt)&lt;br /&gt; { ..blah.. }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This also meant that I can now make my property grid show only properties of Player p1.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PyasagsZ3QA/RjjGhicTqBI/AAAAAAAAAAw/snoIfHHCCkI/s1600-h/playerProperties.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PyasagsZ3QA/RjjGhicTqBI/AAAAAAAAAAw/snoIfHHCCkI/s320/playerProperties.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5060012460834269202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Which is a lot more useful.&lt;br /&gt;&lt;br /&gt;Also evident is the pretty point field I forgot to blog about; this is just a bunch of for loops adding the gravity vector at a point in the grid to the vector to that point.. the result is a point distorted by gravity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-4191628715453530282?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/4191628715453530282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=4191628715453530282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4191628715453530282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/4191628715453530282'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/player-variables-into-player-object.html' title='Player variables into player object'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PyasagsZ3QA/RjjGhicTqBI/AAAAAAAAAAw/snoIfHHCCkI/s72-c/playerProperties.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-8821399556522625156</id><published>2007-05-01T13:47:00.000+02:00</published><updated>2007-05-02T18:43:23.131+02:00</updated><title type='text'>xgame: "Real" time</title><content type='html'>So, I demoed my game on battery power.. and it sucked.  Interestingly whenever windows showed a tooltip, the game ran at full pelt.. something fishy there.

But anyway, I introduced a Δt (delta t for the unicode (or greek) unaware) into my calculations.  

The first stumbling block was that I was using the tick counter, which sucks a bit.  The thing is, even though it has damn good accuracy, it is only updated every now and then.  Which is a bit odd.

I managed to hack it into working by doing the following:
&lt;pre&gt;&lt;code&gt;
private void Physics()
{
    while (System.DateTime.Now.Ticks == Tick) { }
    //time interval
    long thisTick = System.DateTime.Now.Ticks;
    float dt = (Tick - thisTick) / 100000.0f;
    Tick = thisTick;
&lt;/code&gt;&lt;/pre&gt;

But that really feels dirty.  All that hanging around waiting for the tick. - Spoon!

So, anyways. After a bit of ferreting, I found the &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx"&gt;Coding4Fun: Beginning Game Development&lt;/a&gt; article I'd been reading, which contains a section "All about timers".  In summary, I grabbed the dxmutmisc.cs file from the sample code (in DirectX SDK\Samples\Managed\Common), commented out everything but NativeMethods and FrameworkTimer, called &lt;code&gt;FrameworkTimer.Start()&lt;/code&gt; before starting the Main loop, then did
&lt;pre&gt;&lt;code&gt;private void Physics()
{
    dt = (float)(FrameworkTimer.GetElapsedTime()*1000);&lt;/code&gt;&lt;/pre&gt;
to get the time interval since the last physics call.  The *1000 is just to get the number into something I could count on my fingers-and-toes.

And, with a little tweaking of cosmological constants, all was working again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-8821399556522625156?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/8821399556522625156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=8821399556522625156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8821399556522625156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/8821399556522625156'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/05/xgame-real-time.html' title='xgame: &quot;Real&quot; time'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-6273031056949757648</id><published>2007-04-19T12:16:00.000+02:00</published><updated>2007-05-02T18:27:59.963+02:00</updated><title type='text'>xgame: WinForms, OnKeyDown -&gt; DirectInput</title><content type='html'>I wanted to have my game panel run inside a splitter with a collapsible properties panel.  This was quite easy to achieve, merely needing the changing of the handle that directX was pointing at.  i.e. changing this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;d3dDevice = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, flags, d3dpp);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;to this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;d3dDevice = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this.panel1, flags, d3dpp);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;But-it-broke-my-game.&lt;br /&gt;&lt;br /&gt;How? The OnKeyDown event doesn't percolate to parents.  That truly sucks.  Oddly the only key that does percolate is ALT+key which windows needed to get menu key-presses (ALT-F,X) -- ain't that just too hacky.  The mechanism is there, but disabled to frustrate us.&lt;br /&gt;&lt;br /&gt;I didn't really want my players to have to play while holding ALT ;) so I went and figured out how to use DirectInput, with the aid of &lt;a href="http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series1/tut9.php"&gt;Riemer's tutorial&lt;/a&gt;.  And it just works.  Quickly.  &lt;br /&gt;&lt;br /&gt;I'm polling the input from my main loop now, and compared to the handling of the OnKeyDown event I'm getting squagillions more keypresses.  Needless to say ints became floats (Vector3s actually) rather quickly to handle the smaller iterations.&lt;br /&gt;&lt;br /&gt;Other changes include having to have to input de-bounce. I do this by copying the previous state's keys and passing them into the next input parse.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;        private List&lt;Key&gt; Input(List&lt;Key&gt; laststate)&lt;br /&gt;        {&lt;br /&gt;            List&lt;Key&gt; seen = new List&lt;Key&gt;();&lt;br /&gt;            Vector3 rotationInput = new Vector3(0, 0, 0);&lt;br /&gt;            KeyboardState keys = keyb.GetCurrentKeyboardState();&lt;br /&gt;            if (keys[Key.Escape]) this.Dispose();&lt;br /&gt;            if (keys[Key.W]) rotationInput.Y++;&lt;br /&gt;            ...&lt;br /&gt;            if (keys[Key.P] &amp;&amp; !laststate.Contains(Key.P))&lt;br /&gt;            {&lt;br /&gt;                PropertyGridVisible = !PropertyGridVisible;&lt;br /&gt;                splitContainer1.Panel2Collapsed = !PropertyGridVisible;&lt;br /&gt;                OnResetDevice(d3dDevice, null);&lt;br /&gt;            }&lt;br /&gt;        &lt;br /&gt;            ...&lt;br /&gt;            return seen;&lt;br /&gt;        }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And in the main loop:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;        static void Main()&lt;br /&gt;        {   ... &lt;br /&gt;            using (Game grav = new Game())&lt;br /&gt;            {   ... &lt;br /&gt;                List&lt;Key&gt; laststate = new List&lt;Key&gt;();&lt;br /&gt;                while (grav.Created) { ...&lt;br /&gt;                    laststate = grav.Input(laststate);&lt;br /&gt;                    ... }}}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The debouncer was necessary to do 'edge detection' on the squagillion keypresses that I was getting, e.g. to toggle the property pane once only.  The extra call to OnResetDevice is to handle the change in FoV which is done based on the current size of the panel.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PyasagsZ3QA/Rji7vycTqAI/AAAAAAAAAAo/M51YeMBLGb4/s1600-h/properties.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_PyasagsZ3QA/Rji7vycTqAI/AAAAAAAAAAo/M51YeMBLGb4/s320/properties.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5060000611019499522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;End of dev iteration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-6273031056949757648?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/6273031056949757648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=6273031056949757648' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6273031056949757648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/6273031056949757648'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/04/xgame-winforms-onkeydown-directinput.html' title='xgame: WinForms, OnKeyDown -&gt; DirectInput'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PyasagsZ3QA/Rji7vycTqAI/AAAAAAAAAAo/M51YeMBLGb4/s72-c/properties.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-3819445561767956202</id><published>2007-04-17T12:02:00.000+02:00</published><updated>2007-05-02T19:27:34.119+02:00</updated><title type='text'>xgame deliverable one</title><content type='html'>Update: I'm using MDX, Rein's using XNA and Colin has joined us using GL.&lt;br /&gt;&lt;br /&gt;My first deliverable was to have an object in a scene with tilt-to-steer and gravity.&lt;br /&gt;&lt;br /&gt;This is done.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PyasagsZ3QA/RjjJtScTqCI/AAAAAAAAAA4/Wxx159lQLSw/s1600-h/inital.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_PyasagsZ3QA/RjjJtScTqCI/AAAAAAAAAA4/Wxx159lQLSw/s320/inital.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5060015961232615458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;yay!&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The object&lt;/h4&gt;&lt;br /&gt;The object is a triangle list primitive with a single triangle in it.  Each vertex is differently coloured to help with orientation.  It whizzes around quite satisfactorily with a simple spring function restoring it to zero-tilt, resulting in a max thrust of about 70deg.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Gravity&lt;/h4&gt;&lt;br /&gt;Gravity... sucks.  Really.&lt;br /&gt;&lt;br /&gt;Inverse r-squared explodes quite quickly near to the centre, I had great fun experimenting with my singularity-like point-source gravity and watching things magically teleport off into the far reaches of game-space, never to be seen again.  Okay, maybe frustration as well as fun ;) .&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Other things&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;I'm thinking of a few weapon types: a shotgun of low-damage point-bullets, thrust based rockets (possibly steerable).&lt;br /&gt;&lt;li&gt;Planets should bubble into their positioins from the deep below the playing surface, with a bouyant-spring effect upon arriving.  The gravity field vis should ripple away from them as they arrive.&lt;br /&gt;&lt;li&gt;Thinking of indicating a planet's power charge by encasing the planet in a platonic solid, increasing/decreasing count to indicate power.  Maybe CTF-style planet capturing?  Perhaps charged planets repel craft.&lt;br /&gt;&lt;li&gt;Sitting in a gravity field charges the batteries in proportion to the strength of the field. See, in the future they've figured out how to generate power from gravity: It's a cunning arrangement of pulleys, levers, cats and buttered toast.&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-3819445561767956202?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/3819445561767956202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=3819445561767956202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3819445561767956202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/3819445561767956202'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/04/xgame-deliverable-one.html' title='xgame deliverable one'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PyasagsZ3QA/RjjJtScTqCI/AAAAAAAAAA4/Wxx159lQLSw/s72-c/inital.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-117519988798968920</id><published>2007-03-29T22:54:00.000+02:00</published><updated>2007-04-18T10:59:11.310+02:00</updated><title type='text'>xgame begins</title><content type='html'>So, Rein and I decided to have a little compo.  To learn DirectX and make something cool.

The first thing I've been able to come up with is a remake of an old game that used to go by the name of 'VGA planets', not &lt;span style="font-style:italic;"&gt;the&lt;/span&gt; VGA planets, mind you.  With such a name, it's just not possible to find in amongst the birdmen and the borg ( I think they've assimilated the original).

&lt;h1&gt;Spec:&lt;/h1&gt;
We have a bunch of planets which remain stationary, players' space ships which are fitted with inertial drives which can be turned off.

A ship has fuel and a gun.  The gun fires a round that is influenced by the gravity of the planets.  The goal is to fire a round that hits your opponent.

Probably turn based unless I can figure out a good way to balance timing of firing and try to stop dodging.

&lt;h2&gt;Features&lt;/h2&gt;
Based on my initial thinking I'd like to include these features:
&lt;ul&gt;
&lt;li&gt;bump-mapped planets
&lt;li&gt;point sprites spinning into the active player
&lt;li&gt;glowy bullets
&lt;li&gt;tracers
&lt;li&gt;asteroids floating in and around the space
&lt;li&gt;side-scroller-esque (or ala crimson land) power ups
&lt;li&gt;a pong mode (bounce shields around planets)
&lt;li&gt;did I mention glowy bullets
&lt;li&gt;maybe some different guns
&lt;li&gt;and npcs to feast on
&lt;li&gt;landing on planetary bases/docking with orbiting stations for bonuses is hard but rewarding
&lt;li&gt;teleport uses a full tank of fuel
&lt;li&gt;network play
&lt;li&gt;zooming battle field
&lt;li&gt;visual of each players ship at full zoom in the corners
&lt;/ul&gt;
&lt;h2&gt;Physics&lt;/h2&gt;
Draw grid for gravity, green standard, bending in and getting darker, and bending out and getting yellower for anti-grav.

Tilt-based thrust, optional gyro for stabilising; a gyro should align you to the field at that point.
&lt;ul&gt;
&lt;li&gt;elastic physics - springs and things
&lt;li&gt;tilt to steer physics
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-117519988798968920?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/117519988798968920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=117519988798968920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/117519988798968920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/117519988798968920'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/03/xgame.html' title='xgame begins'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-117492671357749091</id><published>2007-03-26T19:07:00.000+02:00</published><updated>2007-03-26T19:31:53.586+02:00</updated><title type='text'>C#: Using StringBuilder with operators</title><content type='html'>&lt;p&gt;So, I had a plane trip ahead of me, and I wanted to be able to use .net StringBuilder with operators, below is the bstring class I wrote to do this.  It's pretty straightforward, except the * operator behaves like python's and additionally is faster than a looped StringBuilder because of the pre-calculation (and allocation) of capacity.  Still trivial, but it makes the StringBuilder useful without having to remember its syntax.&lt;/p&gt;&lt;p&gt;In testing it (obviously) beat the string class and also was indistinguishable from the StringBuilder in all but the * operator, in which case it was faster.&lt;/p&gt;
&lt;pre&gt;    class bstring
    {
        private string _tstring;
        private StringBuilder _string;
        public StringBuilder Builder
        {
            get
            {
                if (this._string != null) return this._string;
                else
                {
                    this._string = new StringBuilder(_tstring);
                    return this._string;
                }
            }
        }
        public bstring(string value)
        {
            _tstring = value;
        }

        public int Length
        {
            get { return Builder.Length; }
        }

        

        public static bstring operator + (bstring stringA, bstring stringB)
        {
            stringA.Builder.Append(stringB);
            return stringA;
        }

        public static bstring operator +(bstring stringA, string stringB)
        {
            stringA.Builder.Append(stringB);
            return stringA;
        }

        public static bstring operator *(bstring stringA, int howMany)
        {
            if (stringA.Builder.Capacity &lt; stringA.Length * howMany)
                stringA.Builder.Capacity = stringA.Length * howMany;
            string tstring = stringA.ToString();
            for (int i = 0; i &lt; howMany - 1; i++)
                stringA.Builder.Append(tstring);
            return stringA;
        }


        public override string ToString()
        {
            if (this._string != null) return _string.ToString();
            else return _tstring;
        }
    }
&lt;/pre&gt;
&lt;p&gt;And here's the body of the test class: in the current state it compares a += loop to the * operator:&lt;/p&gt;
&lt;pre&gt;        static void Main(string[] args)
        {
            bstring bob;
            //bstring joe = new bstring("I am joe. ");
            string bobs = "I am bob. ";
            //string joe = "I am joe";
            int tick = 0;
            int iter = 1000000;
            Console.WriteLine("bstring +");
            tick = Environment.TickCount;
            for (int j = 0; j &lt; 100; j++ )
            {
                bob = new bstring("I am bob. ");

                for (int i = 0; i &lt; iter - 1; i++)
                    bob += bobs;
            }
            Console.WriteLine(Environment.TickCount - tick);
            Console.WriteLine("bstring *");
            tick = Environment.TickCount;
            for (int j = 0; j &lt; 100; j++)
            {
                bob = new bstring("I am bob. ");
                bob = bob * iter;
            }
            Console.WriteLine(Environment.TickCount - tick);
            Console.ReadLine();
        }
&lt;/pre&gt;&lt;p&gt;and the output, showing approx 50% speed increase from pre-allocation on 100 runs of a 1 million part string:&lt;/p&gt;&lt;pre&gt;bstring +
13657
bstring *
7062
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-117492671357749091?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/117492671357749091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=117492671357749091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/117492671357749091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/117492671357749091'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2007/03/c-using-stringbuilder-with-operators.html' title='C#: Using StringBuilder with operators'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-115775263517514096</id><published>2006-09-08T23:46:00.000+02:00</published><updated>2006-09-08T23:58:32.646+02:00</updated><title type='text'>MS SQL: Bad Ju-Ju Magic</title><content type='html'>I call for a vote of no confidence...

Running the statement &lt;code&gt;select count(*) from BagLocations&lt;/code&gt; returned the value &lt;code&gt;19 014 584&lt;/code&gt;.

Then I started the following query:
&lt;code&gt;insert into BagLocations_JuganTemp
select * from BagLocations&lt;/code&gt;

Then, while that was running (it ultimately took 6:33), I ran &lt;code&gt;select count(*) from BagLocations&lt;/code&gt; which returned about &lt;code&gt;3 000 000&lt;/code&gt;.

Then, once the long-running query completed, I ran &lt;code&gt;select count(*) from BagLocations&lt;/code&gt; which returned &lt;code&gt;19 014 584&lt;/code&gt; again, as did &lt;code&gt;select count(*) from BagLocations_JuganTemp&lt;/code&gt;.

Ju-ju bad. Verry badd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-115775263517514096?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/115775263517514096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=115775263517514096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/115775263517514096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/115775263517514096'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2006/09/ms-sql-bad-ju-ju-magic.html' title='MS SQL: Bad Ju-Ju Magic'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-113836775327672882</id><published>2006-01-27T15:08:00.000+02:00</published><updated>2006-01-27T15:16:55.580+02:00</updated><title type='text'>Trump card</title><content type='html'>Eugene's response to &lt;a href="http://forums.storagereview.net/index.php?s=&amp;showtopic=21621&amp;amp;view=findpost&amp;amp;p=222655"&gt;this post&lt;/a&gt; is one of the most amusing refutations I have ever seen on the net.  I won't steal its thunder by quoting, just give it a read if you have 30 seconds to spare.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-113836775327672882?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/113836775327672882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=113836775327672882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113836775327672882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113836775327672882'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2006/01/trump-card.html' title='Trump card'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-113835716071434068</id><published>2006-01-27T11:52:00.000+02:00</published><updated>2006-01-28T01:52:31.133+02:00</updated><title type='text'>MS SQL: Functions and Procedures</title><content type='html'>Functions and procedures in MS SQL 2000 don't play particularly well together.  That's not really a problem, seeing as they both solve the same problem:  running a sequence of operations.  But (and this is a particularly large but) functions offer only a subset of the range of operations available — most notably, they can't alter data in tables or create temporary tables.

So why would anyone use a function?  They're particularly useful as they can return values.  Unlike stored procedures which return an error-code and can pack output variables with data; functions return a value in much the same way as similar constructs in procedural languages.

The 'value' returned by a function can be a scalar value (int, bit, char, &amp;c.) or.. a table.  Scalar-valued functions are useful in a whole bunch of places, but the table-valued function is an interesting beastie.   Table-valued functions behave like views with arguments, so for example:
&lt;pre&gt;a) select question from questions_view where answer=42
b) select question from questions_by_planet('earth') where answer=42
&lt;/pre&gt;In &lt;code&gt;a)&lt;/code&gt; above, all planets would be interrogated for possible questions, those matched to possible answers, then filtered by the where clause.  In &lt;code&gt;b)&lt;/code&gt; interrogation could be performed only on earth (saving a few planets along the way).  In such scenarios, using a function over a view is far more efficient.

Right about now Mr S. Procedure's tappping me on the shoulder to say: "Hey buddy, I do that too.".  Yes, okay, you can achieve the same thing with stored procedures, but they don't provide as elegant a solution.  Functions can literally be dropped in the place of views as if they were merely a view with a more complex name;  to return a table from a procedure requires (to the best of my knowledge) a pretty dance involving creating cursors into temporary tables.

Why did I feel the need to write all this down?  Well, apart from the eminent utility of another description of the differences between functions and stored procedures in MS SQL, I intend to use it as a base from which to describe my recent problems and their resolution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-113835716071434068?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/113835716071434068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=113835716071434068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113835716071434068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113835716071434068'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2006/01/ms-sql-functions-and-procedures.html' title='MS SQL: Functions and Procedures'/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21383536.post-113802403960061678</id><published>2006-01-23T15:37:00.000+02:00</published><updated>2006-01-23T15:47:19.613+02:00</updated><title type='text'></title><content type='html'>Tentatively the mind enters another expression space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21383536-113802403960061678?l=campey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://campey.blogspot.com/feeds/113802403960061678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21383536&amp;postID=113802403960061678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113802403960061678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21383536/posts/default/113802403960061678'/><link rel='alternate' type='text/html' href='http://campey.blogspot.com/2006/01/tentatively-mind-enters-another.html' title=''/><author><name>David Campey</name><uri>http://www.blogger.com/profile/17296053036602866729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
