<?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-3815850801059903543</id><updated>2012-02-02T02:00:30.555-05:00</updated><title type='text'>Diary of a Failed Startup</title><subtitle type='html'>This was a self-funded startup that a college friend and I worked on for a year and a half.  We launched 3 websites in that time.  It ended up going nowhere, but there seems to be a lot of folks asking for stories of startups that just fade away, so I made this blog public anyway.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jonathan</name><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>56</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-4358376047544708269</id><published>2008-12-08T18:53:00.004-05:00</published><updated>2008-12-09T01:44:39.445-05:00</updated><title type='text'>Aftermath</title><content type='html'>It's now been 5 months since Diffle folded, so I figured I'd write one last post to wrap up this blog.  There seems to be a lot of curiosity about what happens to startup founders after their startups die, so perhaps this'll prove informative to people.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Job Hunt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I start work as a UI Software Engineer on Google's Search UI team next month.  The resume effect mentioned in Paul Graham's essays seems to be true: my recruiter said that one factor in their acceptance was the experience of having run my own business, even if it did fail.  (The others were heavy JavaScript experience and strong knowledge of theoretical CS fundamentals, which apparently is not a combination they get very often.)  They thought it would make me a good candidate for leadership roles in the future, which I hope is true, though I'm sure there's plenty to learn on the engineering side before then.&lt;br /&gt;&lt;br /&gt;It's not a panacea, though.  I also applied to Twitter and didn't even get an interview.  Skill fit still matters - being a startup founder is not automatically going to get you a job, though it usually helps.  As does all the other common-sense jobhunting advice, like going through a referral, being nice to HR, dressing well for the interview, following up, and knowing your stuff.&lt;br /&gt;&lt;br /&gt;It also matters what you did in the startup - at my last employer, I interviewed one candidate who had started his own company but outsourced all development to programmers in Russia.  When I asked him what he'd learned from the startup, he said, "That you can't depend on outside programmers.  Other people are unreliable."  He didn't get the job.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Immediate Aftermath&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I didn't realize it at the time, but I was flying when I closed down Diffle - running on pure adrenalin. Part of this was from working with the YC startup, and part was just that entrepreneurship tends to put you into this highly-focused, tunnel-vision state that feels just slighly unreal.&lt;br /&gt;&lt;br /&gt;That all crashed down about a month later, which happened to be about a week and a half after I started the job hunt.  I ended up getting rejected by FriendFeed, and then told the other companies that I wasn't quite ready to go back into the employee world and needed a few months to figure out what I really wanted to do next.&lt;br /&gt;&lt;br /&gt;For anyone faced with winding down a company, I'd &lt;span style="font-style: italic;"&gt;highly&lt;/span&gt; recommend taking a while off before making any big decisions, and not just the two and a half weeks that I'd initially tried.  You're not thinking straight when your startup dies - your perspective may be a bit different in a few months, as might your preferences for what you want to do next.&lt;br /&gt;&lt;br /&gt;The corollary to that is to wind up your startup &lt;span style="font-style: italic;"&gt;before&lt;/span&gt; you're totally out of money, so that you have options for what to do next and don't have to bargain from a place of total weakness.&lt;br /&gt;&lt;br /&gt;Anyway, I ended up developing a &lt;a href="http://eve-language.blogspot.com/"&gt;programming language&lt;/a&gt; for those couple of months.  I'd actually started this about 3 weeks before Diffle, and then put it on hold for the startup.  Whenever people asked me what I'd do if Diffle was a huge success and got bought for enough money to retire on, I said, "Invent a programming language or something."  I figured that I still had a good amount of savings and didn't know what I wanted to do, so I might as well get that childhood dream out of the way and see how far I could take it.&lt;br /&gt;&lt;br /&gt;As it turned out, I decided that this was better off as a part-time hobby project (remember "If your idea starts with 'we're building a platform to...', find a new idea"?  It applies to programming languages as well.)  I'm hoping to continue it, as a hobby project, though I don't know how much spare time I'll have at Google.&lt;br /&gt;&lt;br /&gt;I also spent a lot of this time stripping off pieces of GameClay, cleaning them up, writing docs, and &lt;a href="http://jonathan.tang.name/code/"&gt;open-sourcing&lt;/a&gt; them.  This often took longer than writing the initial code.&lt;br /&gt;&lt;br /&gt;I started pursuing other opportunities around October.  There was a YC startup that was interested in me as a first employee.  A couple friends offered to refer me to big companies (Apple and eBay over the summer, and then Google and IBM in October).  I thought I'd try a cold application to Twitter and Facebook (Twitter ignored me, and I nixed Facebook after realizing I'd probably have to code in PHP).  And I had a whole bunch of other startup ideas.&lt;br /&gt;&lt;br /&gt;I didn't decide what general direction I wanted to go until &lt;span style="font-style: italic;"&gt;very&lt;/span&gt; late in the process - as in, last week or so.  For a while, I thought about just telling the places I was applying to that I was off the market and doing another startup.  Even as recently as this afternoon, literally minutes before formally accepting Google's offer, my mom was telling me about how she'd shared one of my startup ideas with a bunch of prospective customers (teachers - it was education-related) and half thought it was a terrible idea and half absolutely loved it.  That's often the mark of a good idea, so I wondered if I was making the right choice.&lt;br /&gt;&lt;br /&gt;But if I were to do another startup, I'd be stuck with it for the next 4-10 years, it'd have to be profitable within about 2 to avoid running out of money, and this is all in a very uncertain economic climate.  And I have no cofounder, so I'd be doing everything myself until I could afford employees, and then I'd have to build a company culture.  There's no &lt;span style="font-style: italic;"&gt;fun&lt;/span&gt; in that - I might be able to pull it off and get rich, but it'd eat up all of my twenties, probably all my friends, and possibly all my sanity.  Not worth it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;Some additional lessons&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I keep thinking of other things I wish I'd said in the &lt;a href="http://diffle-history.blogspot.com/2008/06/postmortem.html"&gt;postmortem&lt;/a&gt; but didn't think of.  Here're a couple that stick out, though I'm only going to devote a paragraph or so to each.&lt;br /&gt;&lt;br /&gt;The big one: startups are &lt;span style="font-style: italic;"&gt;out there&lt;/span&gt;, not &lt;span style="font-style: italic;"&gt;in your hea&lt;span style="font-style: italic;"&gt;d&lt;/span&gt;&lt;/span&gt;.  You get ideas by engaging with the world around you.  That can mean potential customers, or experts in the field, or lead users, or friends, or even potential investors.  It's really tempting to hole yourself up in your room and code, but unless your idea is &lt;span style="font-style: italic;"&gt;spot on&lt;/span&gt; (and almost no ideas are), this is a recipe for failure.&lt;br /&gt;&lt;br /&gt;Pick a direction and go deep.  I tried a couple other ideas after officially folding up, yet never really got into them.  If you're like most entrepreneurs, it's easy to get overwhelmed by the number of possible things you could be doing.  Ignore most of them, and concentrate only on what you can do better than anyone else.&lt;br /&gt;&lt;br /&gt;It's also really important to be frugal.  This is more apparent after failure than before: frugality gives you options, and you need them.  If you're better positioned than we were, you might even be able to turn failure into victory given enough chances, and cash will give you chances.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I still hope that there's another startup in my future.  It looks like it'll now be several years off in my future, though.  In the meantime, I'm stoked for Google.  I thought the people I met there seemed really cool, as does a lot of the stuff that comes out of there.  Maybe I can even give the "intrapreneurship" thing a try.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-4358376047544708269?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/4358376047544708269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=4358376047544708269' title='128 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4358376047544708269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4358376047544708269'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/12/aftermath.html' title='Aftermath'/><author><name>Jonathan Tang</name><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>128</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-926771987644930564</id><published>2008-06-20T20:33:00.008-05:00</published><updated>2008-06-22T09:14:39.204-05:00</updated><title type='text'>Postmortem</title><content type='html'>So, here's the collection of lessons learned.  I'm going to frame these as advice, but everyone should remember Buchheit's Law: "Advice = Limited Life Experience + Overgeneralization".  This is one startup, and not even a successful one at that.  There are many ways to succeed, and even more ways to fail, and so there will likely be exceptions to every single one of these rules.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If your idea starts with "We're building a platform to..." and you don't have a billion dollars in capital, find a new idea.  Now.&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;This seems to be a really common mistake among first-time founders, particularly those from a technology background.  My last employer made it, and has been working on their platform for the last 7 years with little to show for it (nearly all their revenue comes from a single &lt;span style="font-style: italic;"&gt;application&lt;/span&gt; on their platform).  Early in their development, they had decided that "Well, the only thing all our use cases have in common is that they all involve writing code, so we'll provide a way to write code and handle the tricky business of parallel processing ourselves."  The didn't realize that by making code their user interface, they made Java/C++/Python their competition, and those languages have had literally thousands of man-years of development behind them.&lt;br /&gt;&lt;br /&gt;When I started GameClay, I vowed I wouldn't make the same mistake, and so Mike and I decided there would be no code in GameClay.  Everything would be done through a GUI.  I didn't realize that the problem wasn't code, it was the lack of focus that came with allowing that sort of flexibility.  So as we were building the GameClay UI, I kept getting dragged into all these "Well, we really need this feature to let people do what they want, but it interacts in weird ways with that feature, so we need to rethink the whole thing."  The search space of possible designs was just too huge to tackle.&lt;br /&gt;&lt;br /&gt;Solve a problem, not a class of problems.  Only after you've thoroughly solved that problem can you work on expanding it.  Really, it's okay to not have your product do everything, as long as it does &lt;span style="font-style: italic;"&gt;something&lt;/span&gt; well.&lt;br /&gt;&lt;br /&gt;Interestingly, when you think of many common platforms in use today, they started out that way.  Linux started as a terminal emulator.  The web started as a way to share scientific documents.  Rails started as a collection of code extracted from BaseCamp.  Django started as a collection of code extracted from the Lawrence Journal-World.  PHP started as a way for Rasmus Lerdorf to manage his personal home page.&lt;br /&gt;&lt;br /&gt;The exceptions all seem to be giant corporate projects with money to burn - hence the "and you don't have a billion dollars in capital" caveat in the heading.  UNIX at Bell Labs, the Macintosh at Apple, Windows and then .NET at Microsoft, and Java at Sun.  Big corporations can afford to spend a billion dollars and wait 10 years, though, while startups usually can only afford a few tens of thousands and about 6 months.  You have about zero chance of building and getting people to adopt a platform in 6 months.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;It's a marathon, but it's a marathon made of sprints&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I didn't realize how slowly I was working until I worked with a YCombinator company.  I was making about 6-8 commits/day; they setup a new Subversion repository 2 days ago and it's already on revision 100.&lt;br /&gt;&lt;br /&gt;I was going to title this "Beware the halfhearted effort", but I think that'll be misinterpreted.  When people hear "halfhearted effort", they think "Oh, I'll just work harder."  But there's a limit to how hard you can push yourself.  Programming is a mental activity, and the brain has its own timescale.  If you keep thinking to yourself "Must work faster, must work faster," you'll just end up slowing yourself down.&lt;br /&gt;&lt;br /&gt;Instead, I think that it's absolutely essential to set things up so you get that rush of accomplishment as you finish things.  With GameClay, a lot of my work was basically "Oh, I need to finish this UI widget, and then there's that bug in auto-updating the game when properties change, and...shit, it's not working."  Even when I finished something, I just wasn't that impressed with what I'd done, and it was sorta ho-hum to see it working.  I'd feel drained and spent after coding 2 hours instead of energized.&lt;br /&gt;&lt;br /&gt;A lot of this comes down to picking a problem that's a.) worth addressing and b.) doesn't require a lot of support code to address it.  Early in GameClay's development, I decided that every action the game developer took would instantly update the running game, so they could see their changes immediately.  I thought this was absolutely essential for usability, and it probably was.  But it meant that every single UI widget, whether 3rd-party or written by us, had to be wrapped with functionality to capture all of its events, update the game code, compile it, and then reinstall the new version into the running game loop.  And this all had to be done in the browser, using nothing but AJAX calls.  This was &lt;span style="font-style: italic;"&gt;hard&lt;/span&gt;, and a lot of my time was spent dealing with problems related to this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Initial conditions matter.  A lot.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I started, I'd read everywhere that execution was the important thing and the initial idea wasn't all that important.  I still think that's true, but like most other advice you read on the Internet, it's not the full story.&lt;br /&gt;&lt;br /&gt;The initial idea &lt;span style="font-style: italic;"&gt;does&lt;/span&gt; change, and it's almost certainly wrong.  The thing is, the initial idea determines &lt;span style="font-style: italic;"&gt;how&lt;/span&gt; the initial idea will change, which is crucial to all the execution that follows it.  And the devil is often in the details: little decisions made early on can crucially impact big decisions made later.&lt;br /&gt;&lt;br /&gt;I gave an example above, with the decision to have all updates reflected immediately in the game.  Another choice was the decision to start with arcade games, which was done very early on (even before I joined, I think) without much thought at all.  It was just the first thing that came to mind when we thought of casual gaming, so we said "Let's start with that, and then expand into other archetypes when we have more experience."  We didn't realize that a.) just getting arcade games customizable in a compelling way would be a huge undertaking and b.) we'd ditch the archetypes concept entirely, and so our initial archetype choice became the basis for our product.  Meanwhile, most of the growth in the casual gaming industry has been in puzzle &amp;amp; word games, so we were positioned wrong from the start.&lt;br /&gt;&lt;br /&gt;A third example is the choice to go into gaming at all.  When we started this, a year and a half out of college, that was what we were familiar with and passionate about, and so we didn't really think much about other areas.  But the gaming industry is incredibly overcrowded, and most areas other than game creation have too much competition to be worth entering.  There are hundreds of Flash game hosting sites, you really &lt;span style="font-style: italic;"&gt;don't&lt;/span&gt; want to be a game developer, and MochiAds has a lot of momentum in the game advertising space.  So that's why this is the end of GameClay instead of a transition: if it were a less crowded and more lucrative space, I'd instead think of repositioning things to an overlooked niche.&lt;br /&gt;&lt;br /&gt;All this is not suggesting that you overthink every possible decision at the beginning of the project and make sure you have the &lt;span style="font-style: italic;"&gt;perfect&lt;/span&gt; idea.  You'll never get started if you do that.  But realize that your initial decisions become the base that you take for granted, and you usually never even think about them past that point.  And there's a high, high probability that those decisions are wrong.  It's worth reexamining them after 3-6 months to see if that's still what you want to do.  (We actually did reexamine them, several times, and the answer was still yes, but that didn't make the decisions any less wrong.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing in a vacuum never works.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you look back at early blog posts here, you'll see that the idea hasn't really changed.  That's because it hasn't been in front of many people.  Oh sure, I demo regularly to my former cofounders, and Mike had been showing it around to people at his workplace and a couple potential investors.  But it hasn't really had the sort of rigorous critique that you need to achieve product/market fit.&lt;br /&gt;&lt;br /&gt;The reason for this is that I didn't want to repeat one of the mistakes of my last employer.  They had products that they actually put before a customer and got feedback on - but then the customer's feedback was viewed through the lens of "What does this mean we have to include in our platform?" not "How can we solve the customer's problem in the simplest way possible?"  This was a huge drag on development, since everything had to fit into the original vision.&lt;br /&gt;&lt;br /&gt;I believe that if you have a strong vision, you should go for it.  You may be right or wrong (you're probably wrong ;-)), but at least you find out and can approach subsequent problems with a clean slate.  Don't waste 10 years trying to "work up" to your vision that was probably wrong anyway.&lt;br /&gt;&lt;br /&gt;The flip side of this is that if your vision takes more than a year to execute (I'd actually say 3 months, since that seems to be the limit on your initial enthusiasm), assume it's just not possible in the current environment, and find a new problem to work on.  You want to prove yourself wrong as soon as possible, not spin your wheels forever.  Then you can start the hard work of getting to right quickly.&lt;br /&gt;&lt;br /&gt;I should probably clarify this: this doesn't mean you should shy away from big goals.  Only shy away from big goals where you have to solve lots of thorny problems before you can even put something useful in front of users and get their feedback.  Invent the WWW, not Xanadu.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Beware the chicken and the egg.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A couple of the side-projects we launched had serious chicken-and-egg problems.  Bootstrapacitor, for example, would only be useful if other entrepreneurs used it, yet it needed to be useful before people used it.  Diffle and GameClay had minor chicken-and-egg problems, but we solved them in Diffle by finding lots of free-for-the-taking games on the web and uploading them ourselves.  inAsphere.com, a startup I worked at way back in the first dot-com boom, also had a chicken-and-the-egg problem that prevented the site from really getting off the ground.&lt;br /&gt;&lt;br /&gt;The easiest way to avoid chicken-and-egg problems is simply to have a product that is useful on its own.  Del.icio.us, for example - it's just a bookmark manager that happens to be more useful as more people use it.&lt;br /&gt;&lt;br /&gt;It's also possible to beat chicken-and-egg problems through sheer determination - after all, Reddit, YouTube, FaceBook, Snaptalent, and various other Web 2.0 companies have achieved it.  The way to do it seems to be to make sure you're passionate enough about your own product to use it yourself (like submitting your own stories to Reddit, or how we all created 3-4 sockpuppets at inAsphere and had conversations with ourselves on the forums) and to &lt;span style="font-style: italic;"&gt;get out there and put it in front of lots of other people.&lt;/span&gt;  It's that last point where we failed: we just kinda built the product, launched it, and let it die.&lt;br /&gt;&lt;br /&gt;It really helps to have a passionate, committed cofounder here.  It's pretty difficult both to improve the product (which is critical if you want to show users that you really care enough to be in this for the long term) and to evangelize it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Prototype any 3rd-party libraries that you'll be depending upon, &lt;span style="font-style: italic;"&gt;before&lt;/span&gt; you base your product on them.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We did this with JavaScript libraries - we ran through quick prototypes with Prototype, Mootools, and YUI before finally settling on JQuery.  And we haven't regretted the choice at all.&lt;br /&gt;&lt;br /&gt;We didn't do this with Python web frameworks, and wasted a lot of time as a result.  When I started, I picked web.py because it was the only one I could understand while working within the time constraints of my day job.  Totally the wrong choice - there were a lot of things that web.py just didn't handle that we had to spend a lot of time implementing ourselves.&lt;br /&gt;&lt;br /&gt;Then I went to Pylons, because I had this irrational aversion to Django.  I think Pylons actually would've been okay - it's not a bad piece of software - but it was a mistake to make the decision based on a quick glance at the Django website.  When I actually started using Django for the project, I found it was much more convenient than Pylons had been.&lt;br /&gt;&lt;br /&gt;Another thing to keep in mind: by "prototype", I mean actually write code that exercises a lot of the features of the framework, don't just read the website.  A serious look at the platform turns up many more issues than a superficial glance at a feature list.  Get to know your software before you pick it.&lt;br /&gt;&lt;br /&gt;Actually, one of the things I regret is not taking a deeper look at Ruby on Rails and ExtJS for this project.  I did do a quick Rails prototype for my previous employer, so I'm not completely ignorant of it, but I wish I knew it better when deciding.  But there is limited time for evaluating software, and so the non-Python solutions tended to get short shrift.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If you're doing anything other than building your project and getting users, it's premature.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This was actually something we did pretty well.  We had help, of course: nobody would give us money, so we didn't have the resources to do anything else.&lt;br /&gt;&lt;br /&gt;But when we did deviate from the product/user focus, it was a mistake.  We nearly incorporated too early, back when diffle.com first launched; there was no reason to (nobody was uploading anything anyway), and the bookkeeping involved with being a corporation would've slowed us down significantly.  I also spent two weeks or so load testing the server and doing some performance tweaks, which was completely unnecessary: we never hit more than about 5% CPU usage anyway.  Some of the deployment tools we built never got used; wait till you have something to deploy before you start automating updates to it.  Internationalization support was also a total waste of time.&lt;br /&gt;&lt;br /&gt;Some things we did well on this front:&lt;br /&gt;&lt;br /&gt;We didn't spend all that much time talking to investors.  They probably wouldn't have invested anyway, but if they had it would've been a disaster.  Our idea was flawed from the beginning; I don't think we could've pulled it off without putting 5-10 years into it.  If we'd gotten money, it would simply have allowed us to waste other people's time in addition to our own.&lt;br /&gt;&lt;br /&gt;We didn't worry about corporate trappings - titles, board of advisors, offices, furniture, etc. - at all.  This let us focus on the product and keep our overhead low.&lt;br /&gt;&lt;br /&gt;We didn't spend a lot of time on hypothetical design decisions.  Basically, when one of us proposed a change or new feature, our design process was "Let's try it out and see how it looks."  Oftentimes, the answer was "Terrible.  Let's change it back," but we'd find that out in a day or two (or sometimes just a couple hours) instead of arguing over it forever.  And many times, the process of looking at it suggested a new way of doing things that was better than both the old and the new.&lt;br /&gt;&lt;br /&gt;We didn't spend lots of time trying to partner with big names to offer us credibility.  Okay, we also failed, so it's hard to say whether this would've been helpful or not, but since we failed due to lack of a product, I suspect it'd just have made the failure more public and embarrassing.  Also, big companies tend to be very conservative about lending their brand to support any sort of new startup; it can be very difficult to get them to sign on at all.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The product will take longer than you expect.  Design for the long-term.&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;I need to put this together with the last point, because otherwise I know someone will misinterpret one or both.&lt;br /&gt;&lt;br /&gt;Whenever I had a choice between doing things quick and doing things right, I chose to do things right.  And in nearly all cases, this was the correct choice in hindsight.  This seems to contradict the previous point, so I'll offer a possible clarification:&lt;br /&gt;&lt;br /&gt;Do anything you possibly can to avoid bugs.&lt;br /&gt;&lt;br /&gt;Bugfixing takes unbounded time; it's usually not possible to predict how long it'll take to track down and fix a given glitch.  Moreover, fixing a bug in a dirty code base often introduces 2-3 other bugs that then have to be fixed, creating a nonterminating loop and stack overflow.  I've worked in organizations where 90-95% of programmer time was spent tracking down bugs.  Just think, they're moving 10-20x slower than they could be.&lt;br /&gt;&lt;br /&gt;I should probably mention that this is heavily context-dependent, i.e. the reason why avoiding bugs was such a big win for us was because our product was so damn hard to build, and having a product that was that hard to build was a net &lt;span style="font-style: italic;"&gt;loss&lt;/span&gt;.  So maybe a company that gets the initial product idea right wouldn't benefit from solid development.  Reddit, for example, is famous for just releasing their code and letting their users QA the product.   But the Reddits of the world seem to be the exception - I'd guess that most people are working on products hard enough that they may actually screw them up, and their customers actually care when they do screw up.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;People have an incentive not to crush your dreams.  Take everything they say with a grain of salt.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When we &lt;span style="font-style: italic;"&gt;did&lt;/span&gt; talk to investors, the response was almost universally "It sounds interesting, but I'd need to see a prototype before I invest".  Almost nobody flat-out said "This idea sucks, and you'll never be able to complete it."  (Paul Graham did, but even he couched it in language that was less blunt.)&lt;br /&gt;&lt;br /&gt;Everybody in the startup world knows that big ideas come from unexpected places, and we've all heard the stories about the guy who told YouTube "Nobody would ever want to share videos online" or the guy who told Apple "Nobody would ever want to have a computer on their desk."  They don't want to be that guy.  So they'll encourage you, but say that it's not yet time for them to invest.&lt;br /&gt;&lt;br /&gt;If you really want critical, honest feedback, you need to read between the lines.  Concentrate on proving yourself wrong, not proving yourself right.  It's easy to fall victim to confirmation bias, particularly if you're as passionate about your idea as an entrepreneur needs to be.&lt;br /&gt;&lt;br /&gt;This of course presupposes that you &lt;span style="font-style: italic;"&gt;want&lt;/span&gt; critical, unbiased feedback, and this is debatable.  If I had an accurate assessment of my chances when I started, I would've stuck with my day job, and I'm so much better off now for having tried and failed.&lt;br /&gt;&lt;br /&gt;I guess I'm trying to get across that you should assume that everyone you talk to is being nice, analyze their remarks critically to figure out what they're &lt;span style="font-style: italic;"&gt;really&lt;/span&gt; saying, and then assume that every problem they raise can be solved.  You want to prove yourself wrong, but then use that as a springboard for finding out what the right answer is instead of assuming there's no solution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Know your limitations.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I started GameClay, I was like "I'm a smart guy, I work really hard when I have a sense of ownership of the project, I've got a few years of work experience in fairly related areas, why not?  I'm just as qualified as anyone else to start a startup."&lt;br /&gt;&lt;br /&gt;It turns out that brilliance and dedication alone cannot create a market or solve an intractable problem.  They can help you find out faster if your idea isn't viable, and they may allow you to reach markets that others pass up as too difficult, but there will be some markets that remain out of reach until the environment changes enough to bring them within reach of a dedicated, passionate team.&lt;br /&gt;&lt;br /&gt;That doesn't mean you should shy away from working on hard problems, otherwise there'd be no Apple, or Sun, or Google.  But even the founders of those companies knew their limitations and concentrated on the areas that they were experts in.  Page &amp;amp; Brin, for example, knew they were experts in search and decided that Google would do that one thing well and not worry about anything else.  Wozniak knew he was a damn good engineer and didn't join Apple until it was clear he would &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; be an engineer.   Sun...well, the founders of Sun were each experts in their various domains, and it happened that when you put them together, they basically had all bases covered.&lt;br /&gt;&lt;br /&gt;My problem with GameClay was that there were 3 really hard problems (game design, end user programming, and AJAX-based webapps) and I was an expert in maybe 1 1/4 of them.  Next time I start a startup, I'll perhaps approach it with a little more humility, and pick something that's definitely within my sphere of competence.&lt;br /&gt;&lt;br /&gt;On the plus side, picking a project way outside your limitations is a good way to expand your limitations.  I know so much more now than I did when I started this project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;Ultimately, GameClay failed because I gave up.  Up until that point, it's just a startup that has "not yet succeeded", and so I feel like I should explain &lt;span style="font-style: italic;"&gt;why&lt;/span&gt; I'm giving up:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;I don't think I can do this without a cofounder.  It's very, very difficult to wear both the developer and the evangelist hats at the same time: being a developer requires that you be very pessimistic, so you can see and fix all the problems in your design, while being an evangelist requires that you be very optimistic, so others can feed off your passion.  I suspect that if I tried to do both, the cost would be my sanity, literally, and that's not a price I'm willing to pay for the startup.  Cofounders also help even out the emotional highs and lows inherent in doing a startup, since you're rarely in phase.&lt;/li&gt;&lt;li&gt;I've exhausted the pool of potential cofounders I know.  Amherst College is not really a hotbed of entrepreneurial types, and most of my friends are now either lawyers, in grad school, or have secure corporate jobs.  And I've found that you can't just jump into business with someone: you really need to forge the relationship in a low-stress setting before you subject it to the pressures of a startup.&lt;/li&gt;&lt;li&gt;We're moving too slowly.  This was a problem at my last employer, where it took 7 years and counting to build their platform.  The risk isn't really competitors; most markets develop far more slowly than you'd think.  It's that the whole technology ecosystem changes over time, which makes your initial design decisions a disadvantage against startups that start fresh.  Woe to the companies that started building desktop GUIs in 2002, for example.&lt;/li&gt;&lt;li&gt;There's little outside indication that people want what we're building.  When I run it by friends, most find it interesting, but they find it interesting because I'm doing it and I'm their friend and not because they really understand the idea.  Also, competitors have been significantly less successful than I thought they would be.&lt;/li&gt;&lt;/ol&gt;It's not really the end of my startup journey - I suspect there will be other startups in my future, both as an employee and hopefully as a founder.  But it's the end of &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; startup.  I'm a little sad about that, but I have no regrets about having started it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-926771987644930564?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/926771987644930564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=926771987644930564' title='340 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/926771987644930564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/926771987644930564'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/06/postmortem.html' title='Postmortem'/><author><name>Jonathan Tang</name><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>340</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-3255584637619873490</id><published>2008-06-20T13:17:00.003-05:00</published><updated>2008-06-21T18:27:18.970-05:00</updated><title type='text'>The end, I think</title><content type='html'>Didn't work out with the YC startup.  Their offer was actually quite reasonable, and I think that they'll likely succeed, but I just had a strong gut feeling that this was not the place for me.  I don't want to put myself or them in a situation where I'm just terribly disgruntled six months down the line and then my leaving screws the company.&lt;br /&gt;&lt;br /&gt;The experience of working with a YCombinator startup, even for just a week, was great though.  It's amazing how much energy is in that place - it's like a full notch higher than I was working at, and I thought I worked hard.&lt;br /&gt;&lt;br /&gt;That brings me back to GameClay, which at this point I think is on life support.  And I think it's time to pull the plug.  I remember Sam Altman's response to "How do you tell if you really are doomed?" - it was "If nobody cares about what you're doing and nobody on your founding team cares enough to change that, then you're probably in trouble."  Well, I think that's basically the point we're at now.&lt;br /&gt;&lt;br /&gt;I'm going on vacation in two days, so I think the plan is to create a personal home page, package up all the Diffle stuff that should be open-sourced and open-source it.  Then I want to make this blog public, possibly linking to Subversion and Trac (though since my home page will likely be on a shared webhost, I dunno if I can host the live Trac app).  I'll also write up a postmortem with some of the lessons learned.&lt;br /&gt;&lt;br /&gt;Then, I guess I'll e-mail Paul Buchheit and see if FriendFeed is still hiring.  Actually, I want to work a bit on the &lt;a href="http://eve-language.blogspot.com/"&gt;programming language&lt;/a&gt; I abandoned to start Diffle, see if I can get the hard parts done before I start work again.  So maybe by August/September, I'll be employed again, and that's the end of (this phase of) my startup journey.  Hopefully it won't be the end forever, though - there are second acts, I'm just not ready for them right now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-3255584637619873490?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/3255584637619873490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=3255584637619873490' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3255584637619873490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3255584637619873490'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/06/end-i-think.html' title='The end, I think'/><author><name>Jonathan Tang</name><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>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-8656110828949926177</id><published>2008-06-11T10:15:00.003-05:00</published><updated>2008-06-21T18:25:50.942-05:00</updated><title type='text'>Updates</title><content type='html'>Woah, a month and a half between updates.  A lot has happened since then, development-wise.  I'll try to reconstruct it from the svn timeline.&lt;br /&gt;&lt;br /&gt;When I left off, I was testing performance.  Game performance is *still* inconsistent; I think that O(n^2) collision detection algorithm is really biting us, and we'll have to replace it with something saner.  However, widget performance itself is quite good (except under VMWare), which surprised me a bit.  It's definitely possible to do rich JavaScript UIs with JQuery UI - their speedups in 1.2.6 have helped a lot too.&lt;br /&gt;&lt;br /&gt;I also hooked up the AJAX-compiler infrastructure and image uploading to the backend, so they make real AJAX calls and actually change the behavior of the game.  It was cool to see this working - I don't think anyone else has done anything like this.  Unfortunately we don't have all that many behaviors available - mostly you can just change trajectories, collision behaviors, properties, etc, which is still cool but doesn't really showcase the full power of the technique.&lt;br /&gt;&lt;br /&gt;I had to redo the validation infrastructure to work out the bugs on this.  Lesson learned: error messages matter, and if you can't output pretty, precise error messages, you'll waste far more time in debugging.&lt;br /&gt;&lt;br /&gt;I also made a quickie library that mimics the interface of Justin Azoff's Python MogileFS library but uses local filestorage instead of actually talking to MogileFS.  Been meaning to do this for a while; I was sick of setting up MogileFS every time I did a new install, and it's totally overkill for our current requirements.  So now I can write files to the local hard disk, but just swap out a library and have it work with the real MogileFS.&lt;br /&gt;&lt;br /&gt;The UI is much more fleshed out - nearly all the customizer panels are now done.  I completely redid how they're laid out - there's only a single flat list on the left now, containing all sprite names.  This was done to reduce confusion and eliminate a clickthrough on the sprite category; the result seems to work much better.  I also moved the scrollpane inside the right-hand accordion, to prevent headers from falling off the bottom of the page and requiring scrolling.&lt;br /&gt;&lt;br /&gt;I think we may be within a month or a month and a half of launch.&lt;br /&gt;&lt;br /&gt;Now, I got an e-mail from one of the YCombinator SFP08 groups.  Apparently PG gave my name to them.  Am off to give them a call and see what they want.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-8656110828949926177?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/8656110828949926177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=8656110828949926177' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8656110828949926177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8656110828949926177'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/06/updates.html' title='Updates'/><author><name>Jonathan Tang</name><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>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-332959699976091899</id><published>2008-04-28T12:22:00.002-05:00</published><updated>2008-04-28T12:29:39.465-05:00</updated><title type='text'>Performance reality check</title><content type='html'>Doing a reality check on JavaScript performance today.  I've been running with the game loop turned off for normal development, since there's something about VMWare that makes it about 3-4 times slower in JavaScript graphic performance than a native OS.  But I figured it'd be a good idea to make sure that JavaScript can even handle what we want it to do before I invest lots of (additional) time in building the editor UI.  It'd really suck to write it all and then find we need to rewrite it in Flex.&lt;br /&gt;&lt;br /&gt;So far, the results are - inconsistent.  It starts out fast and then abruptly gets dog slow.  Normally this would point to a memory leak (and I know there are a couple, but they shouldn't have much of an effect at the game sizes we're currently testing), but this is happening really suddenly, and often after a JavaScript error.&lt;br /&gt;&lt;br /&gt;There're a bunch of errors too that may be masking things...I've gotta do quite a bit of debugging before we get useful results.  And the profiler results are not what I expected at all - methods I thought would only be called once are being called thousands of times.  Have to look into that...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-332959699976091899?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/332959699976091899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=332959699976091899' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/332959699976091899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/332959699976091899'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/04/performance-reality-check.html' title='Performance reality check'/><author><name>Jonathan Tang</name><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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6881760788715501509</id><published>2008-04-25T17:23:00.002-05:00</published><updated>2008-04-25T17:42:15.721-05:00</updated><title type='text'>Productive couple days</title><content type='html'>Did I mention in the last post that when it says "3.) Quit and take a job at FriendFeed", I nearly did just that.  Was thinking about e-mailing Paul Buchheit and asking if he's still hiring, but instead I sent out the e-mail that's mentioned in the last post.  Then I talked it over with my parents all Monday, and decided I'll stick with it a bit longer.  It helped that the response of both my PlanWorld friends and former cofounders was quite positive.&lt;br /&gt;&lt;br /&gt;I've had a productive couple days.  Slowly filling in the missing widgets in the editor UI, one by one.  Except it's not really one-by-one, since they're reused so heavily that when I finish one, it pops up in many places.  Pretty nifty.  Still lots and lots of little display bugs - JavaScript programming is really death by Chinese water torture.&lt;br /&gt;&lt;br /&gt;Also helps that the weather has been great, so I've been working outside where there are fewer distractions.  No more dad telling me how war with Taiwan is imminent and we're all going to die.  I always seem to get more done in the spring anyway...in college, my spring semester grades were noticeably better than the fall semester ones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6881760788715501509?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6881760788715501509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6881760788715501509' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6881760788715501509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6881760788715501509'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/04/productive-couple-days.html' title='Productive couple days'/><author><name>Jonathan Tang</name><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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2321773367986866113</id><published>2008-04-21T11:35:00.000-05:00</published><updated>2008-04-21T12:01:54.517-05:00</updated><title type='text'>The problem with the idea</title><content type='html'>Just sent this to the project mailing list for comment:&lt;br /&gt;&lt;br /&gt;I was thinking about the idea last night.  Remember, Mike, when we were rejected from WFP08 I told you that I felt there was *something* wrong with the idea, but I didn't know what it was, and the best way to find out was to keep working on it.  Well, I think I have some idea now.  I'm going to start with a story about my last employer for context:&lt;br /&gt;&lt;br /&gt;My last employer was founded "To manage information flow on Wall Street".  It sounds like a *great* problem - in 2001, everyone saw this as the next big problem for the financial industry.  Several people instantly said "Let me give you money."  He turned them down, but based on the strength of the idea, he self-funded.&lt;br /&gt;&lt;br /&gt;Problem is, "managing information flow on Wall Street" is a huge problem - it's practically the whole financial industry.  So what he actually released was "Something that looks vaguely like a Bloomberg terminal, with charts &amp;amp; graphs &amp;amp; tables and a window where you can write code to manage it."  This sold to maybe 1 or 2 clients; enough to keep going, but not a huge success.&lt;br /&gt;&lt;br /&gt;Then there were a series of other products.  I was hired "to work on hard problems in financial analytics", but what I ended up working on was "a webapp to ensure compliance with an obscure SEC regulation."  Not really what I signed up for...&lt;br /&gt;&lt;br /&gt;So where are we?  GameClay was founded "to let users create their casual games."  It's a bit narrower than managing information flow in the financial industry, but it's still a huge area.  It's not a product, it's a mission statement.  What we're actually delivering is "A webapp that lets users create their own single-player arcade games, as long as they stick to prearranged actions &amp;amp; patterns of movement."&lt;br /&gt;&lt;br /&gt;The question is whether that revised description still makes for a compelling product.  I suspect the answer is yes for Mike, no for me - hence the recent motivational difficulties.  I'm not a huge fan of single-player games; I love multiplayer games, but that's not what we're building.  (Ironically, when I was asking my former boss what his daughter thought of the idea, the note I wrote to myself was "Concentrate on the **multiplayer**", since her comments seemed to focus upon the "playing with friends" aspect.)  I also like puzzle &amp;amp; word games more than arcade shooters and such.&lt;br /&gt;&lt;br /&gt;Remember, users can't see your vision: they can only see your product.  I think that's what's behind PG's response.  He sees the description of what we're doing ("Letting users create their own casual games") and intuitively knows that that's too broad for a product, but he only looks at these apps for like 2 minutes, so he doesn't consciously write that.  Instead, he pulls in all his preconceptions about games ("they're just for teenagers", "they're easy to write", "they're a highly competitive market") and superimposes them on our app to fill in the missing details.  That's why he doesn't "get it".&lt;br /&gt;&lt;br /&gt;So, I guess the next question is what do we do now?  I guess I've got 3 main options:&lt;br /&gt;&lt;br /&gt;1.) Push forwards until launch, then add whatever features are necessary to make a compelling product afterwards.&lt;br /&gt;&lt;br /&gt;2.) Step back and try a different tack, finding another entry point into the casual game creation market.&lt;br /&gt;&lt;br /&gt;3.) Quit and take a job at FriendFeed.&lt;br /&gt;&lt;br /&gt;#1 sounds like the logical choice, and I know you guys are kinda egging me on towards that.  Thing is - I'm not sure it works.  That was the approach taken by my last employer: when they found out that their topic was too broad, they figured "Okay, let's build applications on our platform and show people that it's useful."  But the platform - and all its mistaken assumptions - acts as a drag on future development, making you go *slower* than if you'd just thrown things out and started fresh.  Then everything you do later ends up being harder to use than it otherwise would, because it has the accumulated warts of all the false starts you took.&lt;br /&gt;&lt;br /&gt;There're a couple options for #2 that I want to bounce off people:&lt;br /&gt;&lt;br /&gt;1.) Step back and write *a game*, just a game, and then gradually add customization capability to it.  It'd probably be some sort of chain-reaction puzzle game, since those are the type I most like to play.  But then I've got to come up with compelling gameplay, which can be very much hit-or-miss.&lt;br /&gt;&lt;br /&gt;2.) Start with a *chat room*, and then expand that out so that anyone in the room can place graphical objects on the screen and manipulate them.  Basically, it'd move from chatroom -&gt; multiplayer game -&gt; customizable multiplayer game -&gt; full game creation platform.  The advantage of this is that each individual step is compelling, fairly easily implementable, and useful on its own.  Heck, people even manage to make money charging for chatroom applications.  If the primary draw of games will be multiplayer, might as well do that as the fundamental instead of adding it on as an afterthought.  And I could do like a FaceBook app for chat (I'm amazed people haven't done this yet...FaceBook is supposedly coming out with it as a site feature soon) and put it up.  And if games turns out to be too small a market, I could switch into telecommuting tools (like WebEx), which will likely be huge soon if the price of gas keeps going up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2321773367986866113?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2321773367986866113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2321773367986866113' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2321773367986866113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2321773367986866113'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/04/problem-with-idea.html' title='The problem with the idea'/><author><name>Jonathan Tang</name><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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1177134943962428534</id><published>2008-04-17T01:38:00.003-05:00</published><updated>2008-06-21T18:29:30.539-05:00</updated><title type='text'>More bad news</title><content type='html'>Got rejected from YCombinator.  Again.  Not a big surprise this time, but still disappointing.  PG wrote back; apparently the problem is that the idea is kinda weak, not with the team per se (though I'm sure being a single founder didn't help).&lt;br /&gt;&lt;br /&gt;Carl turned me down for cofounder.  He doesn't think his skill set is really compatible with being a founder-level employee.  That seems to be the story with a lot of my Amherst friends: they aren't really on startup-track careers.  Also asked a former coworker from my last employer who's no longer at the company; he's got a new startup job that he's happy at, so no go there.&lt;br /&gt;&lt;br /&gt;I launched a side-project that took about a week.  Randomicity.  It crawls the web and presents random sites to you.  Launched it two days ago, but as far as I can tell, nobody likes it.&lt;br /&gt;&lt;br /&gt;Still don't know what I'm going to do.  In the near term, I wanna package up some of the open-source stuff I've done for Diffle/GameClay/Randomicity and release it, because it might be useful.  Also looks impressive on a resume.  After that, I dunno.  GameClay is still quite compelling; I may want to finish it just for the sake of finishing it.  OTOH, I seem to be the only one who thinks so.  Maybe I'll just get a job at FriendFeed or some other Valley startup.  Another former coworker offered me a job in his engineering department, but it's for Java (+ JavaScript), and I'm not so keen.  Plus, I kinda feel like I need to get out of the Boston area.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1177134943962428534?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1177134943962428534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1177134943962428534' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1177134943962428534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1177134943962428534'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/04/more-bad-news.html' title='More bad news'/><author><name>Jonathan Tang</name><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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2810037940417853302</id><published>2008-04-01T15:39:00.003-05:00</published><updated>2008-06-22T09:11:56.168-05:00</updated><title type='text'>More founder updates</title><content type='html'>Just asked Carl (a classmate at Amherst) to join as a technical cofounder, but his career's taking him away from pure development and he didn't think he was really qualified to be a cofounder (as opposed to an early employee) of a software startup.  Sigh.  Not sure who else to ask.  One of the downsides of going to Amherst is that the risk-embracing, entrepreneurial, tech-savvy population is &lt;span style="font-style: italic;"&gt;really&lt;/span&gt; small.  Most of my classmates are becoming lawyers or financiers.&lt;br /&gt;&lt;br /&gt;I'm working on getting some bugs ironed out before the YCombinator app is due (I've already got my app in), but the loss of a cofounder really kinda eviscerated the app.  Half the questions are about your relationship with your cofounder.  Looks like this round may not be ours...&lt;br /&gt;&lt;br /&gt;Am trying to decide what to do after that.  I'm tempted to put GameClay aside for a bit and do some side projects that are more tractable, like all the "other ideas" we included on our YC app.  OTOH, the more market research I do, the more I think that casual games are really where it was at.&lt;br /&gt;&lt;br /&gt;If only the particular problem within casual games we'd chosen to take on wasn't so damn difficult.  Then again, if it weren't, then there'd be hundreds of other companies doing the same thing (like with game hosting, or the games themselves).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2810037940417853302?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2810037940417853302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2810037940417853302' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2810037940417853302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2810037940417853302'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/04/more-founder-updates.html' title='More founder updates'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2780355761222538408</id><published>2008-03-28T21:06:00.002-05:00</published><updated>2008-03-28T22:00:02.469-05:00</updated><title type='text'>The end of a cofounder</title><content type='html'>Mike quit last weekend.  He got into Harvard Business School; he actually wanted to continue part-time, but we both agreed that it's not really practical to work part-time on a startup and go to B-school at the same time.&lt;br /&gt;&lt;br /&gt;That leaves me a single founder, at least for now.  I do wanna recruit someone else to join me, but I'm not sure there're all that many prospects.  I don't want to join up with someone I haven't worked with before...that usually tends to be a recipe for disaster.&lt;br /&gt;&lt;br /&gt;I'm going to keep going, at least for now.  The technical end of things is actually going fairly well...we have our first cut at initial archetypes done, they're mostly playable (except I don't have arc collisions done, which makes Brickbats and pong a little impractical), all tests pass, and our backend is basically fairly robust.  Been working on the JavaScript runtime, and soon I'll get back to the editor.&lt;br /&gt;&lt;br /&gt;It just struck me though how lonely it is without a cofounder.  I'd been pretty lonely before, being the sole developer, but at least Mike and I were in this together.   Now it's just me, and I dunno if I can do this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2780355761222538408?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2780355761222538408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2780355761222538408' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2780355761222538408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2780355761222538408'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/03/end-of-cofounder.html' title='The end of a cofounder'/><author><name>Jonathan Tang</name><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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5301252982059118195</id><published>2008-03-17T22:08:00.002-05:00</published><updated>2008-03-17T22:44:25.454-05:00</updated><title type='text'>Misgivings</title><content type='html'>I'm reading &lt;span style="font-style: italic;"&gt;Dreaming in Code,&lt;/span&gt; the history of the Chandler project, and there's an ominous quote from Linus Torvalds:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Nobody should start to undertake a large project.  You start with a small &lt;span style="font-style: italic;"&gt;trivial&lt;/span&gt; project, and you should never expect it to get large.  If you do, you'll just overdesign and generally think it is more important than it likely is at that stage.  Or, worse, you might be scared away by the sheer size of the work you envision.  So start small and think about the details.  Don't think about some big picture and fancy design.  If it doesn't solve some fairly immediate need, it's almost certainly overdesigned.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I worry that this describes us far too much.  We've tried to ground things in real games whenever possible, but I still have this feeling that we're developing too much based on an idea and not enough based on real needs.  Game creation sounds great in theory, but we have no idea whether it'll be appealing when people sit down at a computer and choose what site to visit.&lt;br /&gt;&lt;br /&gt;The big problem at my last employer was that they were building this huge all-encompassing platform, and then only later using it to build applications.  Of course, when we built the applications, we found that all our design assumptions of the platform were wrong, and it was just holding us back.  We never had the will to rewrite the whole platform, so we just dragged around all this code that slowed us down.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5301252982059118195?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5301252982059118195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5301252982059118195' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5301252982059118195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5301252982059118195'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/03/misgivings.html' title='Misgivings'/><author><name>Jonathan Tang</name><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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-923178783513064477</id><published>2008-03-14T12:15:00.003-05:00</published><updated>2008-03-14T13:44:09.526-05:00</updated><title type='text'>First archetypes</title><content type='html'>So, I completed the first archetypes a week ago.  Blank game, editor test, and pong.  It's kinda neat having something up on screen, with some real, movable shapes up.  I added some vector-graphics shapes, because many simple archetypes (pong, brickbats) use plain old colored rectangles or circles for sprites, and even more complicated ones (shooters, etc.) may use circles for bullets and such.&lt;br /&gt;&lt;br /&gt;We also needed shapes for collisions - I got halfway through Pong and then realized it was unplayable without some sort of radial collision detection; otherwise the ball just bounces back and forth in a straight line.  So that's what I'm working on now, and it's fairly slow going - just having rectangles, ovals, and arcs means 6 different cases to test against, each of which has several different cases depending on which axis, which direction the shape is facing, relative positions, etc.&lt;br /&gt;&lt;br /&gt;Been avoiding it by watching basically all of Medium Season 1 &amp;amp; 2.  Unfortunately, it's not that great a TV show, so I've run out of worthwhile things to watch (if any of them were really worthwhile to begin with).  Guess it's back to coding.&lt;br /&gt;&lt;br /&gt;I'm curious what other problems having real, working archetypes will turn up.  I'm very glad we did a minimal "game" and then did the half the editor, because many of our assumptions for data structures were very much wrong, and if we'd done the full game compiler we would've had to rewrite it all.  But now that we're returning to the compiler &amp;amp; runtime, we get to see how many of our assumptions in the editor were wrong, and I'm guessing there are quite a few.  We've already had to add shapes, shape arguments (eg. arc direction), vector graphics, and more complicated collision detection, and likely will need to change how we handle bounce &amp;amp; friction (making them parameters of the collision and not separate actions, for instance).  And some aspects - like victory conditions - need a lot more attention.&lt;br /&gt;&lt;br /&gt;Sometime I should write a post about all our assumptions and how they've been proven wrong and how we've kinda "spiraled" up into understanding, but I think we need a bit more understanding before I can write about it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-923178783513064477?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/923178783513064477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=923178783513064477' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/923178783513064477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/923178783513064477'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/03/first-archetypes.html' title='First archetypes'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-3850642845314001030</id><published>2008-03-03T15:42:00.002-05:00</published><updated>2008-03-03T15:55:22.779-05:00</updated><title type='text'>The game compiler</title><content type='html'>Just finished the game element in the revised compiler, which, being the topmost abstraction in a bottom-up hierarchy, means I've mostly finished the revised game compiler.  Well, module some hard stuff like the collision run-time which I'm putting off till later.  And some easy stuff like background scrolling &amp;amp; images that I just stubbed out and will also do later.  And testing - games and sprites are both untested, though I've been testing out the lower-level abstractions as I build them.  I guess that means I'm not really finished at all.  That's okay; I didn't really expect to be.&lt;br /&gt;&lt;br /&gt;Right now, I feel completely and utterly drained of any coding mojo, and wanna go off and become a fantasy novelist or something.  It doesn't really help that I just looked at Sploder and GameBrix, and they've both launched and are actually sorta moving now.  (Well, technically they'd launched when we started, but we didn't see any movement.)  Now it feels like we're behind and shooting at a moving target.  This is frustrating because I know that if we had working software, I could move faster than they're moving now; after all, I've moved significantly faster on every other project I've worked on (well, except the ones that never got to working software).  But first we have to &lt;span style="font-style: italic;"&gt;get there.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A word of advice to anyone that ends up reading this: pick a problem that you can solve within the first month or two, and then &lt;span style="font-style: italic;"&gt;release something&lt;/span&gt;.  Your initial enthusiasm will burn out within about 2-3 months, and if you don't have something working with users to spur you on, you aren't going to finish.  When Mike first presented GameClay to me, I thought "cool, a project that's at the edge of my abilities, this'll be an interesting challenge."  And it was - the problem is, people (namely myself) always overestimate their abilities, and so something that's at the edge of their abilities is actually just beyond their abilities.&lt;br /&gt;&lt;br /&gt;Actually, we &lt;span style="font-style: italic;"&gt;did&lt;/span&gt; release something within the first couple months - 2 somethings.  Unfortunately they don't have legs; there was nothing to grow from them.  So we needed an idea with more depth, so we did GameClay, which may have too much depth.  Which I guess illustrates the entrepreneur's dilemma perfectly: the easy stuff isn't all that useful, and the useful stuff isn't all that easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-3850642845314001030?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/3850642845314001030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=3850642845314001030' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3850642845314001030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3850642845314001030'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/03/game-compiler.html' title='The game compiler'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-8578454829636328527</id><published>2008-02-22T00:51:00.002-05:00</published><updated>2008-02-22T02:03:09.248-05:00</updated><title type='text'>Abstract vs. Opaque data types</title><content type='html'>So, the problem boils down to the ancient abstract vs. opaque data type debate, which was ultimately responsible for the emacs/xemacs split, and which is one major reason why the Lisp/Python/Ruby folks don't understand the Java/C# folks.  I'm jotting ideas to clarify the issues in my own mind, and on the off chance that folks may find this useful if I de-lock it.&lt;br /&gt;&lt;br /&gt;First, definitions.  An &lt;span style="font-style: italic;"&gt;abstract&lt;/span&gt; data type is a plain old data structure - a dict or list or integer - along with functions to operate on it as a domain object.  You can still reach in and twiddle its innards as a normal hash or list though, and as far as the programming language is concerned, it's just a built-in data type.  An &lt;span style="font-style: italic;"&gt;opaque&lt;/span&gt; data type is a special class with methods to manipulate it, and the language either prevents you from accessing the guts (Java or C++) or strongly discourages it (Python _members). &lt;br /&gt;&lt;br /&gt;Some languages - like Arc, JavaScript or pure Scheme - provide &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; abstract data types, and you need to fake opaque types with conventions.  Other languages - like Java - provide &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; opaque types, and the basic concrete data types are special cases of that.  The languages I tend to use - like Python - provide both, and it's up to you which is appropriate.&lt;br /&gt;&lt;br /&gt;When prototyping, I've almost always found abstract types to be better (or sometimes even concrete types). This is because they don't need to be declared: the interface to an abstract data type is whatever functions you provide to manipulate it, and if you're missing something, you can just use it as a dict or literal.  This lets you change things around very quickly, which is incredibly important when you don't really know what you're doing.  They also tend to be less code.&lt;br /&gt;&lt;br /&gt;In production code, I've found opaque types to be &lt;span style="font-style: italic;"&gt;generally&lt;/span&gt; better, because they provide additional contractual guarantees that are really important when you're building stuff on top of these classes.  You don't &lt;span style="font-style: italic;"&gt;want&lt;/span&gt; the interface to change with every revision, because it'll break everything you've built on top.  Moreover, because the interface is stable (and presumably tested), you can treat the type as a solid black box, which reduces the complexity you need to keep inside your head at once.&lt;br /&gt;&lt;br /&gt;Unfortunately, GameClay is currently in that awkward stage where I don't yet know what I'm doing (in the sense of having detailed interface specifications for each object), and yet I need stronger specification guarantees on the base types in order to move forwards.  I've sorta got a hybrid architecture now, where classes wrap raw data structures and provide accessors.  However, the problem there is that I've gotta remember whether I'm dealing with raw unwrapped structures or wrapped structures with utility methods.&lt;br /&gt;&lt;br /&gt;The cleanest solution in terms of remembering stuff is to bite the bullet, convert the raw JSON structure to language objects when read in, and have all accessors return language objects.  Then I'd need a method to convert it back to JSON data structures.  We can assume that anywhere within the system, once the objects have been constructed, it's all objects, and they all have the appropriate utility methods.&lt;br /&gt;&lt;br /&gt;One pitfall I ran into when I thought of doing this yesterday was that the conversion is somewhat lossy.  For example, expressions are represented by strings in the props structure, but get parsed into an internal data structure.  Printing them back out loses all whitespace and parenthesization.  I suppose I could store the initial prop for expressions, and just omit accessors to change parts of the expression (all our data structures are immutable anyway).  If it's changed by code, it'll have to be changed all at once.  I don't think I have any other places where the representation is lossy.&lt;br /&gt;&lt;br /&gt;Another problem is that this is pretty significant code-bloat.  This is unfortunate, but I'm not sure it's avoidable.  Currently, we're using a decorator to reach inside the props structure and return the appropriate part, but this isn't really correct: it doesn't wrap the props structure with the appropriate class.  If we were to make it correct, we'd need conversion logic, and conversion logic is probably simpler when all in one place.&lt;br /&gt;&lt;br /&gt;A third downside is that we need certain validation state to properly validate objects, and we need to validate before we can safely convert.  The easiest way to do this is probably to pass the state in to the constructor along with the props data structure; the constructor will throw an exception if invalid.  This also fixes my uneasiness about having some constructs throw in the constructor (eg. parsing expressions, actions) while others don't throw until validate is called.  A downside is that validate can't be called standalone, but this shouldn't be necessary: if the props are invalid, you shouldn't be able to create the object, and if you try to call a setter with an invalid value, it should fail in the setter (since objects are immutable and create new ones, this can just re-use the validation from the constructors; however, we need to save a copy of the validation state so that we can invoke the constructor in mutators).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-8578454829636328527?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/8578454829636328527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=8578454829636328527' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8578454829636328527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8578454829636328527'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/02/abstract-vs-opaque-data-types.html' title='Abstract vs. Opaque data types'/><author><name>Jonathan Tang</name><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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1961115377664403800</id><published>2008-02-22T00:32:00.003-05:00</published><updated>2008-02-22T00:51:48.751-05:00</updated><title type='text'>Arc, offers, and hiccups</title><content type='html'>It's weird how I forget about this blog for long periods on end.  Quick update on what I've done in the 3 weeks since the end of January:&lt;br /&gt;&lt;br /&gt;After getting collisions and keybindings to display, I took a break for a week and ported Arc to JavaScript.  It came out in early February, and I was initially going to stay away, but it was just so tempting.  I needed a break from UI widgets anyway, and an interpreter is just the sort of quick project that can provide some variety.&lt;br /&gt;&lt;br /&gt;'Course, that got some attention, which is good for me but bad for the Diffle.  In that week, I got 3 job offers - one from Drew at DropBox, one from my friend Doug out in SV, and one from Paul Buchheit at FriendFeed.  Drew also put us in touch with the FuzzWich guys, and we had a long e-mail exchange back and forth.  Apparently they were working on a game-creation system before they did FuzzWich, and they have some really impressive credentials in game development.  No wonder YC didn't go for us.  The sphere is apparently a tough nut to crack: they kept running up against problems about making the games playable enough to be impressive yet easy enough to create.  Also, apparently my architecture is insane.&lt;br /&gt;&lt;br /&gt;That was probably the closest I've come to quitting so far, between the existence of very attractive alternative offers, and the confirmed difficulty (by people with way more experience in this than us) of the problem sphere, and the prospect of rewriting our whole software in Flex.  I mentioned the job offers to Mike, and he said to do whatever I felt was best, so I'm not really tied down to Diffle. &lt;br /&gt;&lt;br /&gt;But I'm going to stick it out for now.  I'm more convinced than I've been in a while about how this is really a prime space to be in, and that the market's heating up.  The big question is whether we can execute on it, and I'm not sure we can, but the challenge of trying is kinda fun.&lt;br /&gt;&lt;br /&gt;Anyway, I was kinda burnt out for about a week or so after releasing ArcLite (this was when the e-mails were flying back and forth).  When I got back to work, I decided I'd move back to the compiler and update it to meet the full requirements, instead of just the skeleton we've been using to prototype the editor UI.  I also wanted to correct some mistakes in data representations that have really been hurting us on the JavaScript side - we can simplify the editor widgets a lot by making the game data structure more sensible.  This work has been moving along quite well; I initially estimated 2-3 months until full launch when I first set out, but it now looks like we may manage in half that time, barring extraordinary hiccups.&lt;br /&gt;&lt;br /&gt;I'll do a separate post with the current technical hiccup that's been stalling me, for the last few hours at least.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1961115377664403800?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1961115377664403800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1961115377664403800' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1961115377664403800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1961115377664403800'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/02/arc-offers-and-hiccups.html' title='Arc, offers, and hiccups'/><author><name>Jonathan Tang</name><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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-7194541704452957039</id><published>2008-01-31T12:30:00.001-05:00</published><updated>2008-01-31T12:42:32.349-05:00</updated><title type='text'>Insanity</title><content type='html'>Let me just state, for the record, that we're insane for trying to do this, and that I will be fairly surprised if we actually succeed.&lt;br /&gt;&lt;br /&gt;We are, however, still moving.  Since the last update, I restored the server (it's amazing how much easier GameClay is to setup than Diffle...yay setuptools), created widgets to display actions and action sequences on screen, moved all the JavaScript editor to a separate project, created a build script to concatenate them together in dependency order and minify the whole lot, added a bunch of unit tests, auto-generate JSON data for menu items from the GameclayCompiler runtime libraries, and I'm working on refactoring to SequenceWidgets and CompositeWidgets to simplify the customizer code.  I just sent Mike some things he could look into for asset libraries, and will hopefully have a conceptual demo of the UI up fairly shortly for critique.&lt;br /&gt;&lt;br /&gt;I'm going to keep working on this as long as I have money (likely for the immediate future, since I'm still living at home and most of my wealth is in cash) and we're still moving.  I'm noticing that a lot of my startup friends are giving up and getting jobs though - they're spooked by the economy.  In a way this is a good sign, because it means no new consumer websites are coming out and people's attention will be primed for anything good that comes out.  OTOH, it's unlikely that we'll be able to get cash anytime in the near future, which is a little worrisome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-7194541704452957039?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/7194541704452957039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=7194541704452957039' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7194541704452957039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7194541704452957039'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/01/insanity.html' title='Insanity'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-3899976597727343584</id><published>2008-01-17T12:16:00.000-05:00</published><updated>2008-01-17T13:00:34.687-05:00</updated><title type='text'>Editor widgets and recessions</title><content type='html'>I did basically nothing yesterday, other than backing up our server (GoDaddy has a required OS update, so we have to reprovision in the near future.  Better now than after we launch).  But I finished 4 JavaScript widgets in the two days before that, and got the skeleton and structure of the JavaScript game editor in place in the week or so before that.  Seems like I always need time to recharge after periods of high productivity.  Still not fully recharged, else I wouldn't be writing this blog entry, but I've started working on the code to display widgets when a customizer pane is selected.&lt;br /&gt;&lt;br /&gt;I've been watching the turmoil in the financial markets with some interest (perhaps more interest than I should - I oughtta be building the product instead!)   I expected this - one of the main reasons I quit my job was that I was in a financial software startup, and it's highly likely that in a financial crisis my job would be toast too.  I was completely wrong about the timing though.  I figured this would happen in early 2009, after the Beijing Olympics, and we'd have a chance to hit the market and make a big splash before everything went south.  But the recession's a year early and the product always takes longer than we expect, so that's not gonna happen.&lt;br /&gt;&lt;br /&gt;If the recession's a normal one and lasts for about  a year, like 1991 or 1981-1982 recessions, it might be better that things worked out this way.  We underestimated the amount of time it'd take to build the product; if the recession had come in 2009, it would've been just as we were getting to market, and then we'd have to support a (hopefully) growing userbase on skimpy revenues.  While if we entered recession around last October and start recovering around the summer, we'll be just getting known (hopefully) as the recession abates and then get to expand into the recovery.  Same situation that del.icio.us, Flickr, and PlentyOfFish were in, and we all know how it turned out for them...&lt;br /&gt;&lt;br /&gt;There're still a lot of variables though, and given our previous track record of predicting the future, I wouldn't bet on them all coming out in our favor.  At least I've got plenty of cash; as long as I live at home and my mom doesn't lose her pension, I can keep doing this indefinitely, and even if I were to move out and get roommates, I've still got about 3-4 years saved up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-3899976597727343584?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/3899976597727343584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=3899976597727343584' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3899976597727343584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3899976597727343584'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2008/01/editor-widgets-and-recessions.html' title='Editor widgets and recessions'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-3434681763702227702</id><published>2007-12-29T16:37:00.001-05:00</published><updated>2008-06-21T08:44:55.769-05:00</updated><title type='text'>Breaking things up</title><content type='html'>The winner of the last blog entry was Django.  Reading over it again, it seemed that my main objection to Django was that the problem structure - hierarchical data, stored in Mogile, with lots of functions that do things other than CRUDscreen operations (eg. compilation &amp;amp; asset management) - didn't really fit a web framework meant for CMSes.  Other than that, Django would be great, and there were a bunch of 3rd-party Django apps I wanted to use.&lt;br /&gt;&lt;br /&gt;But there's another option - I could &lt;span style="font-style: italic;"&gt;make&lt;/span&gt; the structure of our project fit Django, by pulling all the other stuff relating to the game creation language or compiler out into a separate project.  And I should probably do this anyway, because it leads to a more flexible, more decoupled architecture.   For example, I could run command-line tools that make &amp;amp; publish games and yet don't need Pylons installed.&lt;br /&gt;&lt;br /&gt;So I just spent a couple days pulling everything out into separate projects.  I have one for the compiler (input: a JSON data structure representing the game, output: a Flash file), one for storing things in Mogile, and eventually one for the website itself.  Former 2 are standalone Python projects installed via setuptools, the latter one is a Django project that hopefully will also have a setuptools script.  The compiler passes all its existing unit tests for both Python and Actionscript already, the storage module will be tested in a bit, maybe after dinner.&lt;br /&gt;&lt;br /&gt;I'm kinda surprised (and very glad) that it only took 2 days.  When I did the same thing at my first employer and my last employer (hah, no matter where I work, I end up doing the same job), it took like a month, and in my last employer's case was never finished.  Granted, there I needed cooperation from the other engineers, and they all had other things to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-3434681763702227702?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/3434681763702227702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=3434681763702227702' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3434681763702227702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/3434681763702227702'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/breaking-things-up.html' title='Breaking things up'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2695220066148846407</id><published>2007-12-27T21:08:00.001-05:00</published><updated>2008-06-21T18:45:24.285-05:00</updated><title type='text'>Pylons and Django</title><content type='html'>Thinking about switching the webapp portions of GameClay from Pylons to Django. This would be our third framework (web.py -&gt; Pylons, Pylons -&gt; Django), and Pylons is mostly doing acceptably, though it's pretty annoying in some places and needs some code to fill in functionality that Django provides for free. So this is not something I'm going to do lightly.&lt;br /&gt;&lt;br /&gt;Here's a list of the various aspects and advantages &amp;amp; disadvantages of the frameworks:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Templates&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For Pylons, I'd stick with the default of Mako.  Django comes with its own templating language, but it's not terribly hard to &lt;a href="http://www.djangosnippets.org/snippets/97/"&gt;swap it out&lt;/a&gt;. However, the existing contrib apps expect templates to be written in Django's language, so if we do any customization of contrib apps, we'll need to use Django's. It's probably better to stick with that for all web templates, even though we'll be using standalone Mako in the game compiler.&lt;br /&gt;&lt;br /&gt;Advantages for Pylons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I don't have to rewrite our existing Mako templates&lt;/li&gt;&lt;li&gt;Mako is significantly more powerful than Django, with arbitrary expressions, defs, template inheritance (beyond layouts)&lt;/li&gt;&lt;li&gt;Mako filters get pulled from the template namespace automatically, which is a useful convenience when using potentially lots of filters&lt;/li&gt;&lt;li&gt;Same template system for website and game compiler&lt;/li&gt;&lt;li&gt;I can extend it with defs, in the template, without needing to write a separate Python module to write new tags&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Advantages for Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I like the syntax better; it seems cleaner and easier to remember&lt;/li&gt;&lt;li&gt;Filters can take arguments; useful for things like indent()&lt;/li&gt;&lt;li&gt;The inclusion_tag syntax provides cleaner-syntaxed and more flexible blocks of reusable content than Mako's defs. The pitfall is that these are not defined with the other templates; they live in the template_tags directory.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Models&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For Pylons, I'd use our custom Diffle DB database wrapper.  For Django, I'd use its ORM.&lt;br /&gt;&lt;br /&gt;Advantages for Pylons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Simpler; I know SQL already, don't need to learn a custom model definition language&lt;/li&gt;&lt;li&gt;Can handle multiple databases reasonably easily. It seems very difficult to add this to Django; there's been a branch with it since 2006, but no movement on it. It seems like it'd be a real pain to adapt save() and the query methods to a horizontally partitioned database.&lt;/li&gt;&lt;li&gt;Gives finer-grained control over queries; I can often avoid some extraneous SELECT or UPDATE statements that Django's ORM adds.&lt;/li&gt;&lt;li&gt;Supports multi-column primary keys, something I've found pretty useful in past DB models.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Advantages for Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The model definition classes are actually kinda convenient to use; would eliminate the mental context switch needed to go between SQL and Python. (I can get similar benefits by moving to SQLAlchemy + Pylons, but then I lose the other advantages of using only a thin wrapper).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The admin interface is &lt;span style="font-style: italic;"&gt;very&lt;/span&gt; convenient; it'd let Mike respond to routine complaints from users instead of requiring my intervention. (I might be able to build something similar by introspecting the database, but it'd take time.)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Controllers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Pylons controllers are basically WSGI apps, setup by the "paster controller" script. Django controllers are functions that take a Request and return a Response. Pylons uses WSGI pretty extensively throughout; in order to understand the choices it's made for controllers, it helps to understand WSGI &lt;span style="font-style: italic;"&gt;really well&lt;/span&gt; (I don't, yet).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Advantages for Pylons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Each Pylons controller is its own WSGI app and in theory can use any other WSGI middleware. (In practice, I'm not sure this works, since Pylons constructs the controller objects with each request.)&lt;/li&gt;&lt;li&gt;Provides an easy way to attach data to controllers, like a database or mogile connection&lt;/li&gt;&lt;li&gt;Routes syntax is a little cleaner and more flexible than Django's URL-based dispatching.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Advantages for Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Don't have to use the ugly c, request, session, etc. global variables. Since WSGI apps have a defined signature, they can't take additional parameters, which can be quit inconvenient in Pylons.&lt;/li&gt;&lt;li&gt;Don't need to mess with StackedObjectProxies. Globals themselves aren't suitable for use in a webapp (they aren't threadsafe), so Pylons has its own version of a threadlocal. Unfortunately this is one hell of a leaky abstraction; you can't do dir() or vars() on it and get back anything sensible, and they break when used in generators.&lt;/li&gt;&lt;li&gt;More explicit.  Less to keep in mind.&lt;/li&gt;&lt;li&gt;Less verbose. Controllers are just functions, and they can all live in views.py (though you can break them out into separate modules if necessary). Presumably they could be callables if necessary, though that breaks the next point.&lt;/li&gt;&lt;li&gt;Can be decorated.  Django provides a bunch of useful decorators, like @login_required.&lt;/li&gt;&lt;/ul&gt;I much prefer Django's controller system - it's simple, intuitive, and doesn't have lots of boilerplate. Personally, I think that Pylons' approach of using globals is a big mistake; it was one of the main reasons I moved away from web.py&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Sessions/Login/Registration&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Pylons gives you AuthKit by default, but that looks so unpolished, undocumented, and unsuitable to GameClay that I'd probably have to write my own. Django offers the contrib.auth application, which depends on the Session middleware.&lt;br /&gt;&lt;br /&gt;Advantages for Pylons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Completely flexible, since I'm writing my own. Can include things like IP addresses in the session table, or reference the sessions table to see who's playing which games, or check out what your friends are playing.&lt;/li&gt;&lt;li&gt;Integrates easily with the rest of the app, eg. templates and other controllers&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Advantages for Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Provides usable default controllers for login, logout, and registration&lt;/li&gt;&lt;li&gt;User objects integrated with request; no need to explicitly check for login&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Can retrieve all sessions through Session model; however, session models have only the key and data, and so if we want to search by user or page, we have to do it ourselves. We probably need to use custom middleware for this; we can't do it as a session backend because we don't know the username at that point, and it'd be a pain to do it as an authentication backend because we'd also need to change the Session model and that's not directly accessible.&lt;/li&gt;&lt;li&gt;Handles details like tamper-proof sessions, hashing, generating unique sessions, etc. transparently&lt;/li&gt;&lt;li&gt;Has convenient @login_required decorators for marking posts that require logins.  Also allows filter functions; this could be useful once we have shared games and such&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Other goodies&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;With Pylons, you're basically on your own.  You can use any Python libraries you need, but you can do that with Django too.  Django provides a bunch of nifty features that we might like to use:&lt;br /&gt;&lt;br /&gt;Advantages of Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;CSRF detection.  We need to add this to all our forms otherwise; this is pretty handy middleware.&lt;/li&gt;&lt;li&gt;Redirects.  Particularly if we change the ID or URL scheme.  We don't want to ever break URLs; this could be a handy way to avoid that.&lt;/li&gt;&lt;li&gt;Syndication feeds.  There are Python libraries to do this, but the contrib app is likely easier to use&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Configuration, Packaging, and Testing&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Pylons is based on Paste, setuptools, and nosetests.  Django has its own config and packaging system, and uses doctest and unittest for testing.  The two are roughly equally easy to use - they both provide single commands to setup most things.&lt;br /&gt;&lt;br /&gt;Advantages for Pylons:&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;They handle multiple config files very well.  Each config file is a separate .ini, so you have a test.ini for testing and a development.ini for development and a production.ini for production.  Each of these can be checked in, and you specify the configuration to run when you execute Paster.  Django lets you have multiple settings modules, but you have to switch between them with an environment variable or command-line switch, which is kinda annoying.[edit: the command-line switch turns out to not be that annoying in practice, though a little confusing if you don't know about it.]&lt;/li&gt;&lt;li&gt;Searches for doctests in all locations, not just models and a specific test module.  When you have lots of non-DB code, as we do, there will likely be lots of other stuff.&lt;/li&gt;&lt;li&gt;Easy to specify foreign dependencies via setuptools, and create command-line scripts, and all the other great stuff that setuptools does.  Using setuptools with Django is somewhat clumsy; I hope it's possible.&lt;/li&gt;&lt;/ol&gt;Advantages for Django:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using a Python module as a config file keeps everything Pythonic, and gives some added flexibility&lt;/li&gt;&lt;li&gt;The concept of separate "sites" and "apps" results in a cool architecture where we can potentially utilize other people's contributed apps.  I doubt this will be terribly relevant for us, but it may turn up something neat.&lt;/li&gt;&lt;/ul&gt;Overall, I think Pylons has the advantage for packaging and distribution.  I'm disappointed that Django seems to be moving away from setuptools, even dropping it for packaging the Django distribution itself.  Pylons also really thought through deployment in multiple environments, while Django seems to have done a quick &amp;amp; dirty solution so they could go on to other things.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Other reviews&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;http://pythonmag.blogspot.com/2006/02/pylons-vs-turbogears.html&lt;br /&gt;http://jesusphreak.infogami.com/blog/why_django&lt;br /&gt;http://jesusphreak.infogami.com/blog/vrp1&lt;br /&gt;http://www.cmlenz.net/blog/2006/08/the_python_web_.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2695220066148846407?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2695220066148846407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2695220066148846407' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2695220066148846407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2695220066148846407'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/pylons-and-django.html' title='Pylons and Django'/><author><name>Jonathan Tang</name><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>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5005208744443795874</id><published>2007-12-22T18:53:00.000-05:00</published><updated>2007-12-22T18:57:17.693-05:00</updated><title type='text'>Unit testing</title><content type='html'>Finally got AsUnit to work with MTASC.  There is basically zero documentation on the web for this; I should probably write something up sometime.  Goes on the bottom of my TODO list, after I get everything done for Diffle.&lt;br /&gt;&lt;br /&gt;I rigged it up so we have a Python script that builds the game archetype, then links that against AsUnit and our unit tests and runs all the unit tests through the standalone flash player.  It's pretty convenient - I would've preferred a completely command-line solution that automatically checks all output and doesn't require a GUI, but this is still a single command.&lt;br /&gt;&lt;br /&gt;It found 7 (!) bugs, just in the ActionScript skeleton we've got so far.  Most were silly typoes, forgetting an element of an object hierarchy or passing in an object when we meant a string ID.  But without some sort of testing, we'd never have been able to track them down.  Flash is notoriously debugger-unfriendly, particularly on Linux without the Flash IDE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5005208744443795874?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5005208744443795874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5005208744443795874' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5005208744443795874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5005208744443795874'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/unit-testing.html' title='Unit testing'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6045436731811636868</id><published>2007-12-17T00:27:00.000-05:00</published><updated>2007-12-17T00:56:28.607-05:00</updated><title type='text'>Mental Centering</title><content type='html'>I'm feeling like my mental center of gravity has been shifting more towards Diffle over the past 2-3 weeks.  I remember &lt;a href="http://diffle-history.blogspot.com/2007/10/slow-going.html"&gt;back in October&lt;/a&gt; I felt like I hadn't really "jumped" yet, that something was missing.  It wasn't really a matter of jumping, more a gradual acclimatization as I "detoxed" from my previous day job.&lt;br /&gt;&lt;br /&gt;I kinda want to do a tool that'd graph Subversion commits over time, just to see if this is reflected in actual productivity.  It feels like it is; I think I've done something like 50 check-ins in the past week.  And I'm actually moving fairly quickly on the rewrite.  In the week and 2 days since the last update, I've got a blank archetype all compiling, including expression compiler and all, and the code is much cleaner than the not-incrementally-tested version.  This time around, it's got full unit tests and documentation and I've figured out how to use setuptools and paster to automate the whole build process.&lt;br /&gt;&lt;br /&gt;Some notes on the issues in the last blog posting, so I know why I made certain decisions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;scheme2js was rejected because:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;It can't call out to arbitrary JavaScript functions; they have to be declared, in a way I couldn't figure out&lt;/li&gt;&lt;li&gt;It doesn't generate readable code at all - everything is temps, and it's like it's machine code.&lt;/li&gt;&lt;li&gt;I don't think there's any way I can get it working to generate MTASC code.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;haXe was rejected because external libraries need to be declared, which is a huge extra burden when we use as much 3rd-party JavaScript as we do.  Also didn't seem particularly JQuery-friendly, and the mailing list posts indicated that they had no plans to support it because it was too functional and not OO-enough.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I'm keeping the _root.fn nonsense.  I still hate it, but we don't have a better alternative at this point, and we can always get rid of it via global find &amp;amp; replace.&lt;/li&gt;&lt;li&gt;Leaning towards invoking the compiler via AJAX for the editor issue, though I still need to see how it works in practice.&lt;/li&gt;&lt;li&gt;Canvas tag prototypes went very well - it was quite easy to use, generally cross-browser, and we got some neat effects like lasers and rotation working.&lt;/li&gt;&lt;li&gt;Didn't get around to prototyping the expression language, but I did think more about its design.  There will be an actual parser for it.  However, I'm going to limit to arithmetic/boolean expressions and function calls.  Thinking about making it strongly-typed, with typechecking running via AJAX to tell you if you've made an error as you type.  As for variable scoping, it's pretty simple: I'm introducing keywords "this" and "that", and the name of each sprite type (subscriptable) will also be a variable introduced into the current scope.  Until we have user-defined variables, I don't think we need more.&lt;/li&gt;&lt;li&gt;Didn't prototype worlds larger than the stage; really should, I guess.  I figure that we'll just make sprites children of a 'world' movie, and then move that around to scroll the world.&lt;/li&gt;&lt;li&gt;I got Mike's new layout up and running under Mako.  It looks pretty cool, with all the drop shadows and rounded corners.  Was pretty simple to write too; the HTML really is dead-simple.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Next steps are importing games into Mogile and building the editor.  I expect some fun surprises with the editor.&lt;br /&gt;&lt;br /&gt;Oh, and I wanted to outline the sequence of events that led up to the rewrite, in brief form, because it's instructive of the kind of design pitfalls that hit startups:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Working on the editor, found that I couldn't edit trajectories and have them immediately applied to the game.&lt;/li&gt;&lt;li&gt;Fix would require that the editor have knowledge of individual game archetypes, which would introduce too much complexity.&lt;/li&gt;&lt;li&gt;Dropped the concept of game archetypes with special-cased code.&lt;/li&gt;&lt;li&gt;Because of this, the base game structure needs to have many more options.&lt;/li&gt;&lt;li&gt;This changes the primary data structure we're storing games as&lt;/li&gt;&lt;li&gt;Which touches nearly every aspect of the system, from how games are stored in Mogile, to how archetypes are specified in the codebase, to the type of UI required, to the compilation mechanism.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Which means we might as well rewrite everything.&lt;/li&gt;&lt;/ol&gt;I'm generally much more satisfied with the new architecture though - it's much more flexible and elegant, and since I've eliminated the whole archetype degree of freedom, I can make the editor much more user-friendly and robust.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6045436731811636868?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6045436731811636868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6045436731811636868' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6045436731811636868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6045436731811636868'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/mental-centering.html' title='Mental Centering'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6474085037993209926</id><published>2007-12-07T21:32:00.000-05:00</published><updated>2007-12-07T22:10:29.871-05:00</updated><title type='text'>Rewrites</title><content type='html'>Bit off more than I could chew.  It's now been a week since my last commit, which is usually a signal that it's time to do a revert and start over again.  I got most of the code done and was working on debugging, but then I realized there's no way I can verify the quality sufficiently to have confidence in the code I just wrote.  So it looks like I'll be scrapping it and starting with a simpler feature addition.&lt;br /&gt;&lt;br /&gt;No matter how many times I make this mistake, I always seem to make it once more...&lt;br /&gt;&lt;br /&gt;Actually, I may back up all the way and start from a fresh Pylons project (keeping the bottom-up widgets libraries I've developed, of course, which now account for over half the code).  Now that we have a better idea of the data structures involved, many of the early attempts at a game compiler just seem like extra cruft.  We can also keep the editor, compiler, and game archetypes reasonably in-sync instead of having the compiler and games get way ahead of the editor.&lt;br /&gt;&lt;br /&gt;There are a couple of weak spots that I'm still feeling shaky about and want to prototype some more before I build something that'll hopefully be the final version:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Worlds larger than the stage.  I haven't really played with this in Flash, yet I think it's really important for our initial version.  Games are much more fun when there's more of them offscreen.  We also need to figure out how to edit them in JavaScript - am thinking OpenLayers or Canvas, maybe.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Canvas tag in general.  Nobody seems to use it, but it may be pretty useful for what we're doing.&lt;/li&gt;&lt;li&gt;Expression language.  This is a big one; the existing system is pretty ad-hoc, consisting of simple regexp replacements on what is basically ECMAScript.  We should have some sort of formal language with error checking and a real parser itself.  The existing version isn't even correct in some cases.&lt;/li&gt;&lt;/ol&gt;I also need to figure out how to reflect our changes immediately in the editor, now that we offer full, composable statements.  I figure our options are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create an interpreter in JavaScript for the JSON "language".  Don't really like this one, because then we need to update both the compiler and the interpreter when the language changes, which seems like a pain.&lt;/li&gt;&lt;li&gt;Duplicate the compiler in JavaScript, then eval the resulting function string and place it in the appropriate event handler.  Same issues&lt;/li&gt;&lt;li&gt;Call the backend compiler and have it return a result via AJAX.  This seems like the best option in terms of code duplication, but will result in a delay before the change is apparent.  This may be acceptable, though, as long as it's only a couple seconds.&lt;/li&gt;&lt;/ol&gt;Also, I wanted to look at scheme2js and see if there's any usage for that.  I'm guessing there won't be - we want to serialize our data as JSON for its cross-language benefits, so we'd just have to compile the JSON version to Scheme.  But we do need some way to write library functions that can be used with both MTASC and JavaScript, preferably without the _root.fn nonsense we've got now.&lt;br /&gt;&lt;br /&gt;Maybe I should look into haXe too.  Last time I looked, there were issues with library support - whatever we use for JavaScript needs to support JQuery and probably Canvas.  But at least it'd eliminate the need for MTASC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6474085037993209926?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6474085037993209926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6474085037993209926' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6474085037993209926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6474085037993209926'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/rewrites.html' title='Rewrites'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1327675425202383257</id><published>2007-12-04T21:09:00.000-05:00</published><updated>2007-12-04T21:31:47.358-05:00</updated><title type='text'>Platforms</title><content type='html'>X-posted from a planWorld entry:&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I just followed a link to a  &lt;a href="http://worsethanfailure.com/Articles/The_Inner-Platform_Effect.aspx"&gt;Worse Than Failure&lt;/a&gt; entry, and the article was almost an exact description of my last employer.  Well, not quite, since they programmed in Java and ended up reimplementing a half-assed version of Java, while the article is all SQL.  But close enough.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Maybe it was a good thing that I left.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;It's funny though, when I started my own company, I vowed I wouldn't make the same mistakes as my two previous full-time employers.  And now I'm either making or have narrowly averted making at least a half dozen of those same mistakes.  It's funny how easy it is to fall into those traps.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Note to people who are thinking of starting a software company: do &lt;i&gt;not&lt;/i&gt; start out thinking "I'm going to build a platform for X."  Because X will very quickly become "everything".  And then you'll have a poor imitation of the programming language you used to build it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;At least I know a bit more about programming language design than my last boss did, and have a better idea of the tradeoffs involved.  And Mike's been pretty good at reigning me in and saying "No, we're not going to support that, let's just get a basic game done and worry about extending it later."  So hopefully we can find a happy medium where it's still usable to users without programming experience and yet can build cool things.&lt;/p&gt;Since this is a private blog, I can get into a little more detail here.  The resolution to my last blog entry was to abandon the idea of archetypes.  Trajectories are just one type of stateful interaction that needs to be reset as the user edits the game, and different archetypes may have different ones (shields, for example, or other game properties).  These would all differ in different archetypes, so there's no way to adapt the editor software to handle all possible cases other than to hard-code behavior for each into it.&lt;br /&gt;&lt;br /&gt;Besides, coding up all the different archetypes would be a huge programming burden on me, and we just don't have manpower for it.  Much of the code was shared between them, anyways, yet we have no facility other than our template-based shared libraries for writing routines that can be used by multiple archetypes.  And it limited user freedom - if they wanted a hangman where the body parts moved and could be shot at, they were out of luck.  This opened us up to user confusion, since given flexible enough customization, games could drift quite far from its original archetype.  Users would be asking "Why can't we make this game do what we want, when this other one which is nearly identical can do it?"&lt;br /&gt;&lt;br /&gt;So I ditched the idea entirely.&lt;br /&gt;&lt;br /&gt;I haven't told Mike yet - normally we make all decisions by consensus, but in this case, the alternative is that we can't finish a real piece of software in a reasonable amount of time.  I figure I'd just have to overrule him anyway on technical grounds, and I hate giving people a choice when we don't really have one.&lt;br /&gt;&lt;br /&gt;Unfortunately, that means I've got to be doubly-vigilant about things getting too complicated and technical.  So far the UI seems okay, and aspects of game design actually got simpler from this.  But now I'm finding there are &lt;span style="font-style: italic;"&gt;so many&lt;/span&gt; such aspects, and each has to be handled.  The one that prompted the above blog entry was sprite creation - it's fairly easy technically (we've already got createAt/createOn/createIn actions that handle the various cases), but the UI offers lots of potential choices.  Do we give a separate Creation tab for each sprite, where the user can specify where, when, and how many?  Do we make it an action attached to a timer on the game?  How do we handle randomness in creation?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1327675425202383257?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1327675425202383257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1327675425202383257' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1327675425202383257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1327675425202383257'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/12/platforms.html' title='Platforms'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-4446126074334361707</id><published>2007-11-14T12:26:00.000-05:00</published><updated>2007-11-14T12:44:33.782-05:00</updated><title type='text'>JavaScript, how I loathe thee</title><content type='html'>Random complaint: state is the root of all evil.  I'm trying to get all existing sprites to update their trajectories when the game property's changed, but the trajectory data is duplicated in so many places.&lt;br /&gt;&lt;br /&gt;Of course, I knew this already (&lt;a href="http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/overview.html"&gt;yay Haskell&lt;/a&gt;), but there seems to be inherent state to this problem that can't be programmed away.  For example, bounce/gravity can distort a sprite's trajectory so that its present course doesn't match the specified value; this happens to a single sprite, so we can't have them all share the GameProps' value.  So we're stuck trying to reset trajectories of some fraction of existing sprites.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-4446126074334361707?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/4446126074334361707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=4446126074334361707' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4446126074334361707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4446126074334361707'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/11/javascript-how-i-loathe-thee.html' title='JavaScript, how I loathe thee'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6779239690748498296</id><published>2007-11-12T16:01:00.000-05:00</published><updated>2007-11-12T17:11:56.144-05:00</updated><title type='text'>Widgets done, integrating them</title><content type='html'>About a week ago, I was going to write an entry about the mental stresses that a startup puts on you.  I was trying to figure out how to setup trajectories &amp; actions, and create other sorts of complex behaviors where the options themselves may have parameters and recursive calls to other widgets.  I felt very much like my brain was at capacity, and there was no way I could fit the problem into my head.&lt;br /&gt;&lt;br /&gt;What a difference a week makes.  We've got a fairly comprehensive widget library now, they look reasonably pretty in both IE and Firefox, and I just hooked the shooter archetype up to one.  &lt;br /&gt;&lt;br /&gt;Marc Andreesen's blog entry about the market "pulling" your startup along seems dead accurate.  And it doesn't even have to be a huge market.  Once you've got something up on the screen that looks like you'd use it yourself, it gets much easier to spend long amounts of time on it.  It's like "Oh, look, I can fix that" and before you know it you've spent five hours on it and fixed a dozen bugs.&lt;br /&gt;&lt;br /&gt;There's still lots to do, but I seem to be settling into a routine and getting into the project much more.  It kinda reminds me of when I was little and would play with Capsella or Legos for hours at a time without realizing it was time for dinner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6779239690748498296?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6779239690748498296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6779239690748498296' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6779239690748498296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6779239690748498296'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/11/widgets-done-integrating-them.html' title='Widgets done, integrating them'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6547494765954601548</id><published>2007-10-29T23:18:00.000-05:00</published><updated>2007-10-29T23:33:16.045-05:00</updated><title type='text'>Taking shape...</title><content type='html'>Something I've noticed: as the project takes shape, it starts to pull you along, so it gets progressively easier to ignore distractions.  It's like the project is beckoning you to fill in the gaps.  My news.YC time is way down, Reddit time is down, I've stopped obsessively checking message boards for TV shows (well, mostly - I've got the Kid Nation IMDB page up in the other tab, we'll see if I go for that or the Ubuntu VM that's also in the background after this).&lt;br /&gt;&lt;br /&gt;Also, I wouldn't think of myself as stressed (really, I live with my parents, have plenty of cash saved up, hack all day - which I'd do anyway, and get close to 10 hours of sleep a night), but my body says otherwise.  I usually judge by the number of canker sores, and with 3 plus a cough that I'm nursing, it seems my immune system is pretty shitty right now.  I remember a similar phenomenon at my previous employer...the week or two when the project was done enough to appear on screen yet not finished enough to show anybody were by far the most stressful.&lt;br /&gt;&lt;br /&gt;I wish Blogger had a "current music" field like LiveJournal.  These entries would be all Mike Oldfield, all the time (well, for the past several weeks at least.  Pink Floyd before then).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6547494765954601548?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6547494765954601548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6547494765954601548' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6547494765954601548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6547494765954601548'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/taking-shape.html' title='Taking shape...'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-863750688875681238</id><published>2007-10-24T15:38:00.000-05:00</published><updated>2007-10-24T16:21:13.462-05:00</updated><title type='text'>Archetype #2</title><content type='html'>Productivity is kinda weird.  After actually being social this weekend (Homecoming + meeting up with old coworkers), I got a ton done on Monday (shooter archetype, and redid the customization aspect to factor out some duplication).  Then somewhat less on Tuesday, and virtually nothing today.&lt;br /&gt;&lt;br /&gt;Was going to write a more pensive blog entry, but I think I'll sketch out some architecture ideas instead.  It feels like the software is starting to take shape, yet I don't really know what that shape is yet.  We gotta put this in front of real users soon and make sure we're on the right track.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-863750688875681238?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/863750688875681238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=863750688875681238' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/863750688875681238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/863750688875681238'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/archetype-2.html' title='Archetype #2'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1396697944608549758</id><published>2007-10-18T22:06:00.000-05:00</published><updated>2007-10-18T22:12:33.121-05:00</updated><title type='text'>YC Rejection</title><content type='html'>YCombinator rejection #2 for Diffle and rejection #4 for me.  They didn't even look at our demo, or, for that matter, any of the other hacks we'd linked.&lt;br /&gt;&lt;br /&gt;I can't say I'm not pissed off, though really I'm pissed off as a tool for getting things done.  Actually, in retrospect, I'm only halfway intelligent when seriously pissed off at the world.  Like way back in middle school, or how I finished my CS major in one semester.&lt;br /&gt;&lt;br /&gt;If I disappear from this blog for a while, it hopefully means I'm getting stuff done coding-wise.  Otherwise I'm a complete and utter loser, and I wouldn't want that...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1396697944608549758?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1396697944608549758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1396697944608549758' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1396697944608549758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1396697944608549758'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/yc-rejection.html' title='YC Rejection'/><author><name>Jonathan Tang</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-880633288665372674</id><published>2007-10-12T16:47:00.000-05:00</published><updated>2007-10-12T18:11:30.406-05:00</updated><title type='text'>Demo done</title><content type='html'>So, as you can see (or maybe not see - it'll probably be offline by the time this blog is opened up), we got our demo done in time for the application.  Finished the screencast at 6:00 PM yesterday (the app was due at 10:00 PM), then just resubmitted, ate dinner, and went to bed.&lt;br /&gt;&lt;br /&gt;Was gonna get a lot of the minor stuff fixed today, but I found that I was feeling pretty burned out after the sprint to get the demo ready.  Ended up getting stymied trying to figure out what primary key I should use for games.  Hopefully my coding mojo will return.&lt;br /&gt;&lt;br /&gt;I also have straighten out some dental insurance bit with my previous employer (ugh, previous employers), sign up for health insurance, and write Mike's two recommendation letters for B-school.  The latter is kinda weird, because I'm acting against my own interests - I obviously don't want Mike to go to B-school, because I want Diffle to succeed.  But I'll do it anyways, and do a good job on it, because Mike's a good guy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-880633288665372674?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/880633288665372674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=880633288665372674' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/880633288665372674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/880633288665372674'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/demo-done.html' title='Demo done'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1926505386067112457</id><published>2007-10-11T14:09:00.000-05:00</published><updated>2007-10-11T15:55:05.661-05:00</updated><title type='text'>YC Demo</title><content type='html'>Testing our demo:&lt;br /&gt;&lt;br /&gt;&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="550" height = "430" id="movie"&gt; &lt;br /&gt;&lt;param name="movie" value="http://diffle.com:5000/dev1/0/000/000/0000000124.swf" /&gt;&lt;br /&gt;&lt;param name="quality" value="high" /&gt;&lt;br /&gt;&lt;embed src="http://diffle.com:5000/dev1/0/000/000/0000000124.swf" quality="high" width="550" height="430" name="game" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href = "http://diffle.com:5000/game/1560769668/modify"&gt;&lt;br /&gt;Modify this game.&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1926505386067112457?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1926505386067112457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1926505386067112457' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1926505386067112457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1926505386067112457'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/yc-demo.html' title='YC Demo'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-75998931112861137</id><published>2007-10-10T22:05:00.000-05:00</published><updated>2007-10-10T22:53:45.122-05:00</updated><title type='text'>22 hours till demo time</title><content type='html'>The YC app is due in 23 hours.  We've submitted a version already, but we don't have a demo on it.  We've got 23 - no, a little more than 22 - hours to finish one. &lt;br /&gt;&lt;br /&gt;We're in a much better place code-wise than a week ago.  All archetypes load into the system, you can view them on the web, you can &lt;span style="font-style: italic;"&gt;edit&lt;/span&gt; them on the web, and we've got cool widgets for repositioning and changing images.  Working on saving and publishing now; hopefully will have that done by the time I get to bed.&lt;br /&gt;&lt;br /&gt;The part I'm worried about is installation.  We have a shitload of dependencies, and some of them (I'm looking at you, libxml2 and libxslt) don't seem to want to install.  I hadn't realized how much I take apt-get for granted until I moved from my Ubuntu VM to the RedHat server.&lt;br /&gt;&lt;br /&gt;Mike has already drawn and quartered our demo pieces.  They look amazing...maybe we can actually pull this off.&lt;br /&gt;&lt;br /&gt;So with any luck, things will work perfectly tomorrow.  We'll get the missing software parts done tonight, installation fixed tomorrow, Camtasia downloaded and a demo recorded tomorrow afternoon, and I'll be all set to show Mike and resubmit our application by dinnertime.  If everything goes according to plan.  Hah.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-75998931112861137?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/75998931112861137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=75998931112861137' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/75998931112861137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/75998931112861137'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/22-hours-till-demo-time.html' title='22 hours till demo time'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1753099387471765322</id><published>2007-10-03T10:26:00.001-05:00</published><updated>2007-10-03T11:28:38.335-05:00</updated><title type='text'>Slow Going</title><content type='html'>It's been slow going for the past few days.  One of those stretches where I get to work, think "Oh, I should check news.YC", look at it but see nothing new interesting, head over to Reddit, nothing there, check FaceBook and LiveJournal and Planworld and Yahoo!Finance, come back to project, get a couple more lines in, go read a book, maybe a few function definitions, out for a run, come back, write a few more lines of code, update Diffle blog, and so on.&lt;br /&gt;&lt;br /&gt;I don't really have any working code that I didn't have on Saturday.  Plenty of non-working code, though.  I'm trying to pull together all the Pylons, MogileFS, MTASC, JSON, JavaScript prototypes that I wrote into a single architecture that'll serve as the base for the production system.  This is hard because:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It's a lot to keep in mind at once - storage within DB/distributed filesystem, file formats, duplication of information, how it'll be retrieved and displayed, modification, versioning, compilation, etc.&lt;/li&gt;&lt;li&gt;My natural perfectionist tendencies get in the way and I freak out about this being the real thing and not some throwaway prototype I can do a half-assed job at.&lt;/li&gt;&lt;/ul&gt;In &lt;span style="font-style: italic;"&gt;Founders at Work&lt;/span&gt;, one of the questions that she asked every founder was "Did you ever want to quit?"  I don't really want to quit - there's really nothing else for me, because I don't think I could be happy at a regular desk job where I take orders and code up somebody else's product.  But this is one of those times when I worry that no matter how hard I try, I'll still fall short.&lt;br /&gt;&lt;br /&gt;I also worry that I haven't really "jumped" yet.  A friend of mine put it very eloquently (he was talking about parenthood, having married into a ready-made family, but it applies just as much to startups):&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;"But that's okay. Because once the step has been made -- and J____ never made it -- it's better to be there. Making the leap ahead, taking the plunge, there's a dozen different words for it. J____ stood on the brink for a while, but decided he didn't want to jump. I jumped."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;There's a sort of emotional commitment to startups over and beyond working 12 hour days and quitting the day job.  I'm not sure I have it yet.  For that matter, I suspect that many of the places I've worked didn't have it, given how long it took them to develop software.  It's a matter of becoming one with the problem domain and cranking out code as fast as you can type, because the whole program is there in your head.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1753099387471765322?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1753099387471765322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1753099387471765322' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1753099387471765322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1753099387471765322'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/10/slow-going.html' title='Slow Going'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6805718044082414604</id><published>2007-09-29T13:16:00.000-05:00</published><updated>2007-09-29T13:51:47.589-05:00</updated><title type='text'>False Starts</title><content type='html'>Got a FaceBook message from Bryan asking about incorporation tips and my "first full week away from work".  Has it really been that short?  Actually, I think it's been two full weeks (9/11 - 9/29) and his math is just wrong.  But I certainly remember the feeling of time passing really quickly at work - I remember thinking on several occasions "Geez, it's been a month?  I thought it was only like a week".&lt;br /&gt;&lt;br /&gt;Since last Monday, I've gotten MogileFS working, experimented with the Python API, installed Pylons, and written about 3-4 simple Pylons apps.  Have a decent handle on Routes, Pylons, configuration, packaging now.  I hope.&lt;br /&gt;&lt;br /&gt;I guess it looks like we'll be redoing the web end now after all; basically, I want a simple blank canvas upon which to build our demos.  Seemed easier than trying to integrate it in with the existing Diffle.com site.&lt;br /&gt;&lt;br /&gt;I was thinking recently about all the false starts we've had and things we've had to redo, either partially or totally:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I started with web.py's DB module but ended up ditching it for one I wrote myself&lt;/li&gt;&lt;li&gt;I started with web.py's Cheetah integration, ditched it for standalone Cheetah templates, and then ditched them for Mako&lt;/li&gt;&lt;li&gt;I spent significant amounts of time learning about internationalization and HTTP testing for Python, neither of which we really used&lt;/li&gt;&lt;li&gt;We did RejectedByYC.com, which we repositioned as Bootstrapacitor, which never went anywhere.&lt;/li&gt;&lt;li&gt;We launched as a regular Flash games site which never got significant adoption.  The logic behind that was that we'd need those features anyway, but I'm not sure now that we do, and I think we're better off launching with only our core value proposition (the game creation engine) and adding back social features as we need them.&lt;/li&gt;&lt;li&gt;Initially we were going to use Ming for the Flash compiler; Mike found MTASC and Swfmill and we went with those instead.&lt;/li&gt;&lt;li&gt;I almost completely rewrote Mike's initial MTASC prototypes to fit with our general architecture.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We started using Prototype.js for our JavaScript library, which was replaced by YUI, which was replaced by Mootools, which was replaced by JQuery.&lt;/li&gt;&lt;/ul&gt;I know that in every successful startup, there's a large amount of experimentation and failure that goes on before you eventually find your footing.  But I worry that we may be doing &lt;span style="font-style: italic;"&gt;too much&lt;/span&gt; experimentation and failure, and if some of these failures were really necessary.  I mean, our reasoning sounded logical at the time, but in hindsight some of these (like RejectedByYC/Bootstrapacitor/FlashGames!Diffle) were really kinda dumb.&lt;br /&gt;&lt;br /&gt;Eventually I'll just have to dive in, fully, and whip something up.  And I think we're close to the point I can do that, but not there yet.  It's like I'm still pussyfooting around the edge of the product and not quite ready to make it a reality yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6805718044082414604?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6805718044082414604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6805718044082414604' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6805718044082414604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6805718044082414604'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/09/false-starts.html' title='False Starts'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2324446963027378067</id><published>2007-09-24T19:29:00.001-05:00</published><updated>2008-06-21T19:34:00.923-05:00</updated><title type='text'>Catalog of Mistakes</title><content type='html'>8 hours later, I've got both JavaScript and Flash versions compiling from a single source, and am working on installing MogileFS for the full architecture.  Never did get to the YC app, though.&lt;br /&gt;&lt;br /&gt;Time for a quick catalog of mistakes we've made since we started.  I'll add to these as we make more, and then perhaps publish the whole thing once we've overcome them all and actually have an audience.  [edit: didn't actually add more, that's what the postmortem is for, but I've added little edits with commentary]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Personnel:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Founder on a student visa.  Xin had to leave because his visa wouldn't let him work on a startup.&lt;/li&gt;&lt;li&gt;Too many uncommitted founders.  We started with 5 founders, with a wide degree of commitment between them.  It doesn't work - communication overhead eats up any added manpower they provide.&lt;/li&gt;&lt;li&gt;Quitting the day job too late.  Now that I know the difference in productivity, I definitely would not have stuck with the day job this long.  Then again, my opinion may change if we fail or come close to running out of money.  [edit: nope, still feel the same way.]&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Technology:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;web.py.  It's just too poorly-supported and unpolished at this point, with some design decisions that are just dumb.  Will replace with Pylons, probably, but it's a low priority.  [edit: and then Django]&lt;/li&gt;&lt;li&gt;Cheetah.  Mako is better.  [edit: and Django is...I dunno about better, but I like the Django + Django package more than Pylons + Mako]&lt;/li&gt;&lt;li&gt;Prototype/YUI/Mootools.  Ditched all of them in favor of JQuery.&lt;/li&gt;&lt;li&gt;Writing too much from scratch.  If I had to do it over again, I'd probably use Pylons or Django.  Then again, writing from scratch probably gave me new perspectives on how to use the framework features, so it may be unavoidable.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Strategy/Positioning:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Too many side projects.  A couple times, I suggested doing a side project "on the off chance" it succeeds.  Problem is, if the passion isn't there for the idea, you won't be able to follow-up enough to see whether it'll really succeed.  We'd be better off pushing through on our main idea and doing our best to make it succeed.  If it fails, *then* is the time for side projects.  [edit: OTOH, many of the other opportunities that I'm pursuing came from side projects I did instead of GameClay.]&lt;/li&gt;&lt;li&gt;RejectedByYC.com.  Yeah, we found out that putting "rejected by" in the name of anything isn't a good way to get users.  And the replacement "Bootstrapacitor" was too vague.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Diffle the Flash games site - if there are hundreds of competitors already, nobody is going to pay attention to the hundred-and-1st.&lt;/li&gt;&lt;li&gt;Not explaining what the site is about - it's not always obvious to other people.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Legal:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The attempt to get an IP release and protect us from claims that we developed software while employed by someone else failed.  Employer wouldn't sign it.  It may be moot anyway, since it looks like we'll end up rewriting nearly everything by the time we actually re-launch.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Will add to these as more come up.  Time for the Heroes season premiere now...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2324446963027378067?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2324446963027378067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2324446963027378067' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2324446963027378067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2324446963027378067'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/09/catalog-of-mistakes.html' title='Catalog of Mistakes'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6171506949569759568</id><published>2007-09-24T11:59:00.000-05:00</published><updated>2007-09-24T12:22:55.407-05:00</updated><title type='text'>A week and a half of freedom</title><content type='html'>It's now been a week and a half, nearly two weeks, since I quit the day job.  And so far, it's appeared that that was exactly the right thing to do.&lt;br /&gt;&lt;br /&gt;It's not really the time issue.  I estimate that I work maybe 8-9ish hours a day of actual productive time on Diffle, broken into 3 hours or so when I first wake up, another 2 hours or so before dinner, and then 3-4 hours at night.  I certainly couldn't do that with a day job, but it's only a factor of two or so more than I could manage in my spare time, and my productivity is way more than a factor of two higher.&lt;br /&gt;&lt;br /&gt;Rather, it's what it does to my attention span.  Before, those 4 hours a day were broken into 45 minutes or so before work, 45 minutes before dinner, and maybe two hours after dinner when I'm all tired out.  By the time I actually get into the work, the amount of usable time is really more like zero.  So essentially all useful work was done on weekends.&lt;br /&gt;&lt;br /&gt;Also, I find that I'm thinking much more clearly.  I'd stumbled around for about 2 months as to an overall architecture for game editor + JavaScript version + Flash version.  It came to me about 2 days after quitting my day job.  My code is cleaner and nicely factored.  Mike remarked at how simple and intuitive the hangman prototype I put together is.&lt;br /&gt;&lt;br /&gt;Anyway, a quick list of things I've done since quitting:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;jQuery documentation &amp;amp; dependency tool&lt;br /&gt;&lt;/li&gt;&lt;li&gt;YC News in polar coordinates - the cloudmaps stuff didn't really work right (despite spending a few days on it), so I replaced it with a simple polar plot during DevHouseBoston.  Was generally a success; did most of it during the hackathon, cleaned it up and added a couple other features in the two days afterwards, and posted it on news.YC.  Will include in our YC app as a cool hack.&lt;/li&gt;&lt;li&gt;Hangman prototype - it took about 2-3 days to get up-to-speed with MTASC, Swfmill, and ActionScript.  I've got a basic fluency now, along with a prototype.  Converting it to JavaScript took only a couple hours, and now I'm working on a compiler to generate both from the same source.&lt;/li&gt;&lt;/ul&gt;Also thought out a distributed architecture for storing games and such.&lt;br /&gt;&lt;br /&gt;Am about to start working on the YC app.  Mike did a draft last week, now we have to condense things down, since it's too wordy.&lt;br /&gt;&lt;br /&gt;Also should start a post with a list of all the mistakes we've made.  There's a tendency to white-wash the past, so might as well get them all down while they're fresh and painful.  Might be interesting, and hopefully we can avoid making them again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6171506949569759568?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6171506949569759568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6171506949569759568' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6171506949569759568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6171506949569759568'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/09/week-and-half-of-freedom.html' title='A week and a half of freedom'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-7939763535865468947</id><published>2007-09-11T18:07:00.000-05:00</published><updated>2007-09-11T18:44:06.251-05:00</updated><title type='text'>Last day</title><content type='html'>Has it really been 5 weeks since last update?  A quick catalog of what's happened since then.&lt;br /&gt;&lt;br /&gt;It's so weird to look back on the last post and see "YUI toolkit".  We ditched YUI for Mootools, mostly because the Windoo extensions had a resize handle implementation that we could use off-the-shelf.  And then we ditched Mootools for jQuery because apparently the Mootools community is a bunch of arrogant pricks (heard secondhand, but heard from many people) and jQuery is where the momentum is now.  Of course, jQuery doesn't have a resize handle plugin (or many of the things in Mootools or YUI really, though it's getting better fast), so I had to write one myself.  That took like a week.&lt;br /&gt;&lt;br /&gt;We've now got a pretty good library of jQuery stuff - 3 plugins and a documenter/dependency analyzer, which I hope to release as open-source.&lt;br /&gt;&lt;br /&gt;I sometimes worry if we're wasting too much time on ancillary tools and not spending enough on the core product.  Really, a &lt;span style="font-style:italic;"&gt;majority&lt;/span&gt; of the time has been spent on tools, server setup, prototypes, learning other tools, etc.  And this has been convenient in some regards (one-click deployment, w00t), but I can't help wondering what the state of the product would be if the time had been invested in it instead.  And now I'm doing a little widget for DevHouseBoston3 that isn't really related to the product but which might give us a better chance of being accepted to yCombinator.  I feel like I really just need to devote a big solid block of time to just pushing stuff out and get it done.&lt;br /&gt;&lt;br /&gt;Speaking of which, today was my last day at my day job.  It's kinda bittersweet, I guess - these important life transitions always are.  But I really can't do both that and the startup, and I'm not willing to let the startup go.  Now I'm free to work crazy hours and hack crazy stuff.  Liberating, but a little scary.&lt;br /&gt;&lt;br /&gt;The IP release was a big bust.  My employer wouldn't sign it, so the approx. $1K it cost and 5 weeks it took is basically down the drain.  Well, technically the cost isn't, since my pay for those 5 weeks is more than it cost.  But the time &lt;span style="font-style:italic;"&gt;hurts&lt;/span&gt;.  I hope that it doesn't cost us our market opportunity.&lt;br /&gt;&lt;br /&gt;Moreover, it made my boss think that we had something nefarious going on.  (How could he not have heard of similar agreements?  Steve Wozniak had one!)  I guess no good deed goes unpunished.&lt;br /&gt;&lt;br /&gt;Anyway, it's all behind us.  Tomorrow - or maybe even tonight, depending on if I can get the cloudmaps for DevHouseBoston done tonight - I get to really put in some time on the game creation engine.  It's exciting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-7939763535865468947?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/7939763535865468947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=7939763535865468947' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7939763535865468947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7939763535865468947'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/09/last-day.html' title='Last day'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-2700289406456239085</id><published>2007-07-30T13:02:00.000-05:00</published><updated>2007-07-30T14:08:29.285-05:00</updated><title type='text'>Incorporation etc.</title><content type='html'>Wow, I seem pretty full of myself in the last post.  I stand by the general sentiment, though if I were to rewrite it, I would probably use fewer literary metaphors.  And I think that at this time I basically have made my decision - I'm leaving as soon as the lawyer comes through with incorporation and IP release.&lt;br /&gt;&lt;br /&gt;Speaking of lawyers, we met with Sam Mawn-Mahlau of Edwards Angells Palmer &amp; Dodge on Monday.  He's the same guy who litigated the Ars Digita custody battle for Phil Greenspun.  It was basically a massive infodump that left my head hurting for hours afterwards - I had tons of questions, and he brought up tons of issues we hadn't even thought of.  For anyone thinking of starting a company, I'd recommend meeting with a &lt;span style="font-style: italic;"&gt;good&lt;/span&gt; lawyer (with experience in the particular area of business you're in) as soon as you're sure it's something you really want to do.  It can be really expensive (we're expecting a bill of about $4K for this incorporation and releases) but it's generally more expensive &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; to take care of it.&lt;br /&gt;&lt;br /&gt;I've been prototyping the game-creation engine this whole time.  As I think I've mentioned in previous posts, we have the conversion-to-flash stuff all prototyped-out by Mike, and I got it to build on Linux.  We also have a pretty decent translation to JavaScript, so you can pretty much play it using DHTML only.  The next step is to get the actual customization going, which has presented some pretty thorny interaction-design issues.  We want it to update the game behavior &amp; appearance in real-time, which a.) means lots of observers and b.) means we need to specify and customize a lot of properties that don't have obvious visual representations.  Without getting into scripting languages, how do you specify "When the user presses space, create a new PlayerBullet at the location of Player", for example, or let them add different bullet types?&lt;br /&gt;&lt;br /&gt;Now I'm looking at the YUI widget set and trying to do a few prototypes with it.  I want to avoid having to write all my own widgets from scratch, as there are a lot of little gotchas with JavaScript that can cause little bugs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-2700289406456239085?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/2700289406456239085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=2700289406456239085' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2700289406456239085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/2700289406456239085'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/incorporation-etc.html' title='Incorporation etc.'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-4622377871833473847</id><published>2007-07-22T11:46:00.000-05:00</published><updated>2007-07-22T12:17:22.657-05:00</updated><title type='text'>To really live, you must be willing to die</title><content type='html'>&lt;blockquote&gt;"You are the true master of death, because the true master does not seek to run away from Death.  He accepts that he must die, and understands that there are far, far worse things in the living world than dying."  -- Albus Dumbledore, &lt;span style="font-style: italic;"&gt;Harry Potter and the Deathly Hallows&lt;/span&gt;&lt;/blockquote&gt;A &lt;a href="http://news.ycombinator.com/item?id=35931"&gt;comment &lt;/a&gt;by staunch on news.YC really clarified this decision for me.  Startups are much like the archetypical Hero's Journey: there's the call to adventure, when you get the initial idea for it, there are sidekicks &amp; partners, there are hopefully hands-off mentor figures, there are tests and tribulations and temptations, and if you're lucky there's a happy ending where the hero embraces his destiny, overcomes his competitors, and sells out for millions of dollars.  Of course, this is real life and not a fantasy novel, so there's about an 80-90% chance that the hero goes broke and gets another day job, wiser and more skilled yet somewhat embittered.&lt;br /&gt;&lt;br /&gt;The critical success factor, though, is that the hero first acknowledges all his doubts and fears and then embraces them.  So yeah, failure is a very real possibility.  In the storybooks, that means death.  In startups, it merely means that nobody likes what you're doing and you're wasting your time &amp; money, and you may go broke.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://paulgraham.com/procrastination.html"&gt;Big problems are scary&lt;/a&gt;.  I've found that this has been a significant problem for me.  I could do RejectedByYC/Bootstrapacitor in 3 weeks, because I just looked at it as a distraction from Diffle, so it wasn't important, so I could just throw things up on the screen and make it work.  I could do Diffle, because once we had finished Bootstrapacitor, it was just a distraction from the game creation engine, so it wasn't important and I could get it up on the screen.  I've slowed down markedly on the game creation engine, because &lt;span style="font-style: italic;"&gt;this is what we've been wanting to do all along&lt;/span&gt;.  What if nobody likes it?  What if it flops?&lt;br /&gt;&lt;br /&gt;I guess the answer is: so what?  If it flops, I've built up skills in web design, Python, JavaScript, lots of cool AJAX stuff, etc.  I can try other ideas.  I have money in the bank.  It's not gonna kill me to spend a year working on random startup ideas.&lt;br /&gt;&lt;br /&gt;This also answers the question Todd asked me: when are you gonna quit?  And the answer is: when we run out of ideas.  As long as we have something to do, why not do it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-4622377871833473847?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/4622377871833473847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=4622377871833473847' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4622377871833473847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4622377871833473847'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/to-really-live-you-must-be-willing-to.html' title='To really live, you must be willing to die'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-4085227542207839210</id><published>2007-07-20T18:20:00.002-05:00</published><updated>2008-06-21T20:40:01.927-05:00</updated><title type='text'>Objections</title><content type='html'>I had a long conversation with Frank, and then Sheldon, at work today.  Dunno if it was intended to get me to stay or if it was just to let me know some of the pitfalls of startups - it seemed like a little bit of both.  Anyway, I want to write down some of the objections they had so I can come back to them and we can perhaps address them.&lt;br /&gt;&lt;br /&gt;From Frank:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Advertising/sales expenses.  It takes money to let people know about your product.  You can have the best product out there, but if folks never hear about it, they won't use it.&lt;/li&gt;&lt;li&gt;Development costs - it sucks to spend $90M and then find there's no market out there.&lt;/li&gt;&lt;li&gt;The company's business is really picking up - I could be missing out on a very exciting time.&lt;/li&gt;&lt;li&gt;We should at least validate the market by sending links to an impartial potential customer (he offered his son) before plunging in&lt;/li&gt;&lt;li&gt;Much of our hurry may be premature - we can watch our competition, see if they take off, and try to catch up with them afterwards&lt;/li&gt;&lt;/ol&gt;From Sheldon:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We should at least be able to convince angel investors to invest money, even if we don't take their money.  If we can't convince them, how can we convince customers?&lt;/li&gt;&lt;li&gt;I'm too young with too little technical experience for this&lt;/li&gt;&lt;li&gt;It'd suck to spend all this time building a product and then find that we were building the wrong product.  All that development effort would go to waste.&lt;/li&gt;&lt;/ol&gt;One of the biggest mistakes entrepreneurs can make is confirmation bias: disregarding information that doesn't fit the course of action they've decided upon.  I'd really like to avoid that trap here, so I'm writing down these objections here so I can come back to them impartially.  Unfortunately, almost all of these are just &lt;span style="font-style: italic;"&gt;opinions&lt;/span&gt;: they aren't factually verifiable, which makes them a bit hard to test.&lt;br /&gt;&lt;br /&gt;There's also a problem in that knowing more and knowing way less than a person both seem the same: in both cases, they look stupid to you.  I mentioned this problem to my friend Doug when I first joined my last employer: there were business decisions Sheldon made that seemed a little off, but I couldn't tell whether he was dumber than me or way smarter than me.  Doug reassured me that he was probably not way smarter than me, but that's not really enough to go on.&lt;br /&gt;&lt;br /&gt;I think I have a solution to that: I've e-mailed Sheldon asking for the most influential books/websites/blogs/resources in his company's growth.  Because while you often can't tell if a person's opinions are wrong (you have no idea what experience they base it on, after all), you can tell if their &lt;span style="font-style: italic;"&gt;reasoning&lt;/span&gt; is wrong.  If you know what they know and then can point to specific flaws in their assumptions, you can answer the question of whether you're smarter or way dumber than someone.&lt;br /&gt;&lt;br /&gt;I'm not willing to wait and see how the competitors do.  The problem with these highly viral consumer web services is that they'll sit with no adoption until you solve &lt;span style="font-style: italic;"&gt;the whole problem&lt;/span&gt;, and then everyone will try to use them at once.  Once you've solved the whole problem, there's no way for a competitor to squeak in until another problem manifests itself, because users are happy as-is.  Most cases where people say "Oh, there was no market" really are cases where there is a market, but there do not exist services on the market that solve the whole problem.  For example, YouTube could not exist without FaceBook/MySpace, easy video-editing software, and cell-phone video, because there was no easy way for users to make and edit videos and no audience for them once they did.  Reddit could not exist until the rise of blogs and news sites, because there was not enough freshly-updated content to make it interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-4085227542207839210?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/4085227542207839210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=4085227542207839210' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4085227542207839210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4085227542207839210'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/objections.html' title='Objections'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-6031417180808862957</id><published>2007-07-19T10:03:00.001-05:00</published><updated>2008-06-21T20:31:49.907-05:00</updated><title type='text'>Leaving</title><content type='html'>I gave notice yesterday.  Went reasonably well - boss said he'd like to keep me, but he's obviously not going to twist my arm, and we left open the possibility of some consulting or part-time work in the future.  I did have to listen to a long lecture about how it's too early, my chance of success in negligible, I don't have the technical chops, etc.  Ah well - I did hear some things that I'll want to keep in mind anyways.&lt;br /&gt;&lt;br /&gt;A quick selection of quotes I've heard from various people around me when I mentioned I wanted to go full-time on the startup:&lt;br /&gt;&lt;br /&gt;"So, mom and I were talking about your startup in the car, and while we think it's great that you're trying - we honestly don't think you'll succeed." - my sister&lt;br /&gt;&lt;br /&gt;"Don't quit your day job!" - my dad&lt;br /&gt;&lt;br /&gt;"But how are you going to eat?" - Cindelius, a netfriend&lt;br /&gt;&lt;br /&gt;"So you're basically going to play the lottery?" - Todd, a coworker&lt;br /&gt;&lt;br /&gt;"If you can't even convince me that a market exists for this product, how are you going to convince investors or customers?" - Sheldon, my boss&lt;br /&gt;&lt;br /&gt;These quotes are perhaps a bit unfair and out of context - Cin and Todd have actually been quite supportive, and even the boss &amp; family members just want to make sure I'm aware of the risks.  But I thought I'd put them up there for posterity's sake.  [Edit: Yeah, and they were exactly right. ;-)]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-6031417180808862957?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/6031417180808862957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=6031417180808862957' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6031417180808862957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/6031417180808862957'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/leaving.html' title='Leaving'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-8747777481679396199</id><published>2007-07-18T12:00:00.001-05:00</published><updated>2008-06-21T20:27:26.172-05:00</updated><title type='text'>Quitting the Day Job</title><content type='html'>This is really a work-up-the-courage-to-give-my-boss-notice post, but I also want to jot down some of my thinking, just to clarify things in my own head and make sure that I'm not making a huge mistake.&lt;br /&gt;&lt;br /&gt;I had initially wanted to start a startup straight out of college.  My idea at the time was for collaborative editing, a la SubEthaEdit but over the web.  As it turns out, Google Docs has implemented the same feature now, so it wasn't a horrible idea, but it wouldn't've worked out anyway because I would've just ended up competing against Google.   The reasons I didn't start it and ended up taking a day job instead:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Upon looking at SubEthaEdit's market again, they weren't really getting widespread adoption.  There was some niche interest, but few people using it for actual work, and those who were tended not to care about the collaborative editing features.  What failed for SubEthaEdit was unlikely to work for us.&lt;/li&gt;&lt;li&gt;I didn't have money.  Coming out of college, I had roughly $10K saved from my year at Traxit, sitting in a tax-free municipal bond fund.  I had about $3-5K in my bank account from summer work.  I figured that legal fees would easily eat $5K, hosting would eat a couple hundred a month, health insurance would eat a couple hundred a month, and I really didn't want to be mooching off my parents, though I did end up living at home anyway.  That didn't leave much runway.&lt;/li&gt;&lt;li&gt;I felt that I frankly lacked the experience to start a startup.  Yeah, I had taken FictionAlley.org's new system from conception to completion (or actually, I only completed it in November after finishing college).  But I had no idea what people would actually pay for, how legal and financing stuff works, common mistakes that startups make, how to manage programmers if we ever were to grow beyond just me, or anything like that.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I'd only taken two projects successfully to completion (Scrutiny and FictionAlley), and FictionAlley felt like it was a big stretch.  I worried that I lacked the discipline to carry something as big as a startup all the way through.&lt;/li&gt;&lt;/ol&gt;So I decided to take a job at someone else's startup and learn how it's done while saving up money.  Best of all worlds, except I had to leave my startup dreams behind for a couple years.  With luck, I'd do some side projects and something would take off, then I could quit once it looked like it'd be successful.&lt;br /&gt;&lt;br /&gt;Fast forward a year and a half to now.  The status of each of the 4 points above is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I mentioned our competitors in my last post.  Sploder has a forum with a bunch of people that are pissed off because its founder is no longer maintaining the site.  GameBrix has gotten some tech press coverage.  MyGame has a bunch of games actually created by casual browsers.  It looks like our competitors are about to get traction - if we delay any longer, they'll leave us in the dust.&lt;/li&gt;&lt;li&gt;I have close to $40K in the bank, another $20K in the brokerage account, and $35K of Akamai stock I could sell.  If I were to move out and live like a grad student, the cash in the bank would cover close to 2 years, and then the stock accounts nearly 3 years more (assuming no market crash, and we'd be fucked anyway in that case).  That's after paying lawyers for incorporation and buying out the silent partners.&lt;/li&gt;&lt;li&gt;From what I've seen at my job and what I've read from other successful founders, startups are simpler than I thought.  It basically comes down to three rules: 1.) Make something people want, 2.) Charge more for it than it costs you, and 3.) Fix problems now rather than later.  We do 3 and hopefully 1 already; 2 will have to wait because of the market, but that just means we have to keep costs very low to start out.  Of course, there's a lot of complexity behind each of the individual points, but that complexity depends heavily on the particular market opportunity.  It's not something you can take with you from job to job.  We'll just have to develop that expertise as we go along, which means we need time and focus to work on it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Since college, I've added Write Yourself a Scheme in 48 Hours, a Netbeans Plugin for work, Bootstrapacitor, the Execution Monitor for work, and now the Diffle flash games site to that.  Each of those had places where I wanted to forget about it and read Reddit at the time.  In each case, I came back and finished it.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;I've also tried to eliminate as much risk as I could from the decision to go full-time on Diffle.  The way I see it, the various forms of risk inherent in a new business are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Enthusiasm risk.  You may get started and then find that you don't like your business idea as much as you thought you did, once you have to start doing actual hard work.&lt;/li&gt;&lt;li&gt;Team risk.  Your cofounders may have divergent goals, and the team may fall apart.&lt;/li&gt;&lt;li&gt;Technological risk.  You may not be able to build what you're hoping to build.&lt;/li&gt;&lt;li&gt;Market risk.  It's possible that nobody will want what you build&lt;/li&gt;&lt;li&gt;Economic risk.  You may not be able to build what people want at a price they're willing to pay for it.&lt;/li&gt;&lt;li&gt;Competitive risk.  Someone else may build what people want better than you.&lt;/li&gt;&lt;li&gt;Scaling risk.  If you build everything way better than everyone else builds it, you may not be able to scale your infrastructure to the demand this creates.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Enthusiasm risk was a big worry when I started, and the reason I didn't quit the day job immediately.  But I think it's fairly likely that that's behind us: I'm finding I'm &lt;span style="font-style: italic;"&gt;more&lt;/span&gt; excited by the actual process of working on this startup the farther we get.&lt;br /&gt;&lt;br /&gt;Team risk actually happened to us, but we've basically dealt with it.  Our 3 former cofounders seem willing to be bought out.  It was an expensive mistake, but much less expensive that allocating 50% of the equity to 3 people who aren't really interested in being day-to-day involved with the business.&lt;br /&gt;&lt;br /&gt;We've tried to reduce technological risk as much as possible.  We are live with the actual website now - it's unlikely that any surprises will crop up there.  We have prototyped command-line compilation from XML to Flash, so we know we can do that, and it's nothing more than string manipulation in Python.  We've prototyped building a game in JavaScript, and succeeded with adequate performance.  I'm working on customizing that game in real-time through JavaScript, but it seems like that should work without major hitches.&lt;br /&gt;&lt;br /&gt;We still have to live with market risk.  Ideally, I'd stick with the day job until Diffle took off and it was &lt;span style="font-style: italic;"&gt;clear&lt;/span&gt; that people wanted our system, so we'd only have to worry about scaling risk.  However, in the presence of competitors, &lt;span style="font-style: italic;"&gt;they&lt;/span&gt; are more likely to take off and get users if the market actually exists.  By trying to ameliorate market risk, we open ourselves up to competitive risk.&lt;br /&gt;&lt;br /&gt;Economic risk is typically not a problem for software startups, because your variable costs are so low.  If people like what you build, there will be &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; way to monetize that profitably.  Often it involves selling out completely to a big company, but software that gets used almost always is a net economic positive.&lt;br /&gt;&lt;br /&gt;Finally, we're still very exposed to scaling risk.  But that'll only get worse if I still have my day job.  And if we get to the point where this is a problem, I'll be jumping for joy.&lt;br /&gt;&lt;br /&gt;I figure that worst case, I try this for a year, see how far we get, and if it was a complete mistake, I go get another job.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-8747777481679396199?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/8747777481679396199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=8747777481679396199' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8747777481679396199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8747777481679396199'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/quitting-day-job.html' title='Quitting the Day Job'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-213557670319123590</id><published>2007-07-17T22:24:00.000-05:00</published><updated>2007-07-17T23:02:35.356-05:00</updated><title type='text'>Competition</title><content type='html'>We've found 4 competitors in the past week and a half: &lt;a href="http://mygame.com/"&gt;MyGame&lt;/a&gt;, &lt;a href="http://www.gamebrix.com/"&gt;GameBrix&lt;/a&gt;, &lt;a href="http://www.sploder.com/"&gt;Sploder&lt;/a&gt;, and &lt;a href="http://gamescene.com/Make_Your_Own_Game.html"&gt;GameScene&lt;/a&gt;.  Each of them is more advanced than us.  In GameBrix's case, they've been working on it since at least January 2006, and probably have some sort of funding.&lt;br /&gt;&lt;br /&gt;Still no more traction on Diffle.com.  I can't really blame people: right now, it has nothing to recommend it over any other site on the Internet.  There're a bunch of features I'd like to implement, but it's hard to get a good continuous block of time.  I typically have about 20 minutes in the morning while eating breakfast, a half hour before dinner at night, then in theory I've got 2-3 hours before going to bed, but it's usually broken up into hour chunks by shower/dishes/taking out the garbage/etc.  It's hard to get into flow with only an hour, particularly at the end of the night. &lt;br /&gt;&lt;br /&gt;(For a while I was doing okay by timeshifting things and going to bed immediately after dinner, then working in the morning.  But this only worked while things were relatively light at work.  I find that I need more sleep the more that I program, so I was going to bed at 10 and waking up at 8, the same time I would've woken up had I gone to bed at midnight.)&lt;br /&gt;&lt;br /&gt;I've decided that I'm going to quit my day job.  Planning to give my boss advance notice tomorrow, though it may be a month or two until I'm actually done.  We have to get an IP release signed before I leave; Mike is talking to a lawyer tomorrow night.&lt;br /&gt;&lt;br /&gt;We're going to try for yCombinator funding again.  Obviously I hope we get it, though having been rejected by them 3 times before, I'm not too optimistic.  Mike will quit his day job for the program if we get funding, in February if not.&lt;br /&gt;&lt;br /&gt;Still no more traction on Diffle.com.  I can't really blame people: right now, it has nothing to recommend it over any other site on the Internet.  There're a bunch of features&lt;br /&gt;I want to implement, but I don't have a solid block of time to implement them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-213557670319123590?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/213557670319123590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=213557670319123590' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/213557670319123590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/213557670319123590'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/competition.html' title='Competition'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-94779480338749078</id><published>2007-07-12T13:03:00.000-05:00</published><updated>2007-07-12T13:32:29.248-05:00</updated><title type='text'>Launch</title><content type='html'>Long stretches of time without posts are good things.  It means I'm working on coding rather than blogging.&lt;br /&gt;&lt;br /&gt;I suppose I should've put up an entry about the launch when we launched, but a.) I was too busy and b.) there really wasn't a clear launch date...we sort of slid into it, and we're still sorta sliding into it.  This just happens to be the first time I've got time to blog instead of code.  So I'll try to reconstruct what's happened since the last entry, almost a month and a half ago.  There's bound to be a useful lesson in here somewhere...&lt;br /&gt;&lt;br /&gt;We went live on Tuesday, June 26.  "Went live" as in "Okay, password protection is off, you can tell your friends about it."  I suppose our official launch date was July 1st: that was when Mike put one of our games on Digg to test the waters.&lt;br /&gt;&lt;br /&gt;As of the last post (May 31), we were "Just about to launch - this is the last feature we need, really."  This seems to be a common feature of startups: FictionAlley was "ready to launch in a couple of days" for about a month before it actually launched, my day job has been "ready to launch" for the last two months but with little actual activity on that front, and Diffle was "one day away from launch" for about 3 weeks.  So it's worth looking at the Subversion commit log to see where that time was actually spent.&lt;br /&gt;&lt;br /&gt;On May 31, I was working on auto deployment.  I didn't actually commit those changes until Jun 2, my birthday, and then it's only "beginnings of auto-deployment".  I finished (with a big ? in my commit log message) on June 5, then we had to fix bugs in the main production script that only showed up after deployment.  June 7 involved adding the ability to change passwords (oops!  how could I forget that), June 8 was some bugfixes, and June 9 began a pretty page for handling internal server errors, which I didn't actually finish and debug until June 12 (there were no commits between June 9 and 11 - I was at Chris &amp; Jess's wedding).&lt;br /&gt;&lt;br /&gt;The next week was all bugfixes - there were a lot of them, apparently.  I think I actually removed the password protection on June 20 (the same day I added the custom 404 not found page - there are 8 commits that day, I must've did a whole lot of other bugfixes too).  There are a couple fixes there that IIRC came from suggestions by Mike's girlfriend Sandy, so it would've been open to at least her.  Then I had to convert all templates to precompiled Cheetah templates to fix a unicode encoding issue - this was the last bug before launch, I discovered it about an hour before we were about to go live and decided it was enough of a showstopper to postpone the launch.  It took about 2 days to convert everything to precompiled templates, then we went live on June 26, though we didn't actually tell anyone about us. &lt;br /&gt;&lt;br /&gt;I went on vacation - no Internet access - for the 4th of July week, which was one of the main reasons we didn't actually tell anyone.  Spent the time prototyping the game creation engine - I should jot down some thoughts on that soon, because they're undoubtably wrong.  Mike dugg a game anyway, to see the response.  We ended up getting like 700 unique visitors from that, but the site really isn't sticky.  The vast majority (like 93%) came and left without checking anything else out.  Since then, we've been holding steady with about 20-40 uniques a day.  I suppose that's somewhat encouraging, that at least *somebody* checks us out daily, though it's not much.  Mike and I both think we really need the game creation engine in order to take off.&lt;br /&gt;&lt;br /&gt;Aside from that - we had to switch from Cheetah to Mako because Cheetah offers very poor handling of AJAX fragments.  There's no real facility in Cheetah for libraries of mixin HTML fragments: basically, each def needs to be either on the page or in a parent class.  Mako is much more flexible, with both inheritance and namespaces, and also seems to have more robust unicode support and an easier API.&lt;br /&gt;&lt;br /&gt;I should start the main Diffle announcement blog so it's not just a blank page.  It's at diffle.blogspot.com, and will be the public face for announcements and status updates and such.  This will continue to be more internal reflections and so on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-94779480338749078?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/94779480338749078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=94779480338749078' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/94779480338749078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/94779480338749078'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/07/launch.html' title='Launch'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-4771740731747479656</id><published>2007-05-31T12:43:00.000-05:00</published><updated>2007-05-31T17:01:57.291-05:00</updated><title type='text'>Doing nothing, really</title><content type='html'>I spent most of last weekend watching basically all of Heroes season 1.  I did get some stuff for Diffle done (like a utility to do diffs of database schemas, and another one for diffs of directory trees), but far less than I would've liked to.  My brain basically felt fried all through the long weekend.&lt;br /&gt;&lt;br /&gt;I hear stories about "the startup life" and how people basically work 24/7, and wonder if this means Diffle is fated to mediocrity.  I guess nobody will be reading this if that's the case, so I shouldn't worry too much about it.  I've found that I can put in couple-week-long stretches of fairly hard work (moreso because the darn day job means I'm fighting fires all day at work), but I crash afterwards and just basically veg out for a week or so.&lt;br /&gt;&lt;br /&gt;Still, I guess we've gotten quite a bit done since the last entry, nearly a month ago.  We put about a week of work into Bootstrapacitor after the second launch before giving up.  I suppose I should write a post-mortem for that.  Then I did the layout for Diffle and got far more intimately familiar with HTML/CSS than I ever wanted.  Mike was working on the shooter game for the full Gameclay site during this time...it looks pretty impressive already.  Then there was performance testing, some indexing, some missing features like prefs and the feedback form, and auto-deploy.  Am working on auto-deployment now; it's the last major thing we need in place before launch.  Well, that and figuring out what's wrong with our e-mail server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-4771740731747479656?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/4771740731747479656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=4771740731747479656' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4771740731747479656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/4771740731747479656'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/05/doing-nothing-really.html' title='Doing nothing, really'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-912034749264492655</id><published>2007-05-01T14:30:00.000-05:00</published><updated>2007-05-01T14:41:16.507-05:00</updated><title type='text'>Bootstrapacitor</title><content type='html'>Relaunched Bootstrapacitor yesterday evening.  &lt;a href="http://news.ycombinator.com/comments?id=18233"&gt;Response &lt;/a&gt;is still a resounding thud.&lt;br /&gt;&lt;br /&gt;There's some feedback, but still no users.  I suspect the feedback is masking the real problem: people just don't need it.  The story doesn't fit into people's lives.  So even if it &lt;span style="font-style: italic;"&gt;looks&lt;/span&gt; like a good idea, they won't use it.&lt;br /&gt;&lt;br /&gt;Gonna switch focus to Diffle for a bit.  A lot of the code we wrote for Bootstrapacitor actually consists of bugfixes for the Diffle framework &amp;amp; libraries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-912034749264492655?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/912034749264492655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=912034749264492655' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/912034749264492655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/912034749264492655'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/05/bootstrapacitor.html' title='Bootstrapacitor'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-8613329380545621595</id><published>2007-04-25T10:44:00.000-05:00</published><updated>2007-04-25T12:37:00.716-05:00</updated><title type='text'>RejectedByYC.com</title><content type='html'>I launched RejectedByYC.com yesterday at 3:00 AM, to a resounding &lt;span style="font-style: italic;"&gt;thud&lt;/span&gt;.  Response was generally negative, mostly because people didn't like the RejectedByYC name and logo.  Too negative, too close to yCombinator, and basically too much of a ripoff.&lt;br /&gt;&lt;br /&gt;So Mike and I brainstormed some ideas.  Eventually we came up with Bootstrapacitor, from "Bootstrap" and "Capacitor", the idea being that we store up energy until the startup explodes in a bolt of lightning.  There're also neat potential puns with the flux capacitor, which after all is shaped like a Y(Combinator).  And we're not going back to the future, we're inventing the future.&lt;br /&gt;&lt;br /&gt;Yesterday I added the stats page, and this morning I moved the announce link to the layout (for those who've already registered startups) and added Markdown support.  Mike came up with a logo last night, so I may try to add that in today and adjust the layout.  And we've already registered bootstrapacitor.com, so the site needs to be switched over to that domain.&lt;br /&gt;&lt;br /&gt;We are facing an issue over time allocation, though - in many ways, Bootstrapacitor is a distraction from our main business, which is Flash game creation.  Mike has made a lot of progress on the game creation engine, so we'll want to launch Diffle.com and start integrating games in with it.  I'm hoping that Bootstrapacitor is something that'll speed things up and give us publicity, but if it flops again, we may be better off just concentrating on the games and pushing that out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-8613329380545621595?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/8613329380545621595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=8613329380545621595' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8613329380545621595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8613329380545621595'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/04/rejectedbyyccom.html' title='RejectedByYC.com'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5106721948032887818</id><published>2007-04-12T15:39:00.000-05:00</published><updated>2007-04-12T17:04:34.984-05:00</updated><title type='text'>yCombinator</title><content type='html'>The yCombinator responses came on Tuesday, and...we didn't get in.  I have a bunch of suspicions why, but ultimately it boils down to them only being able to interview 30 groups and us not being one of them. &lt;br /&gt;&lt;br /&gt;I was feeling pretty bummed for about an hour, then I read some of the comments on news.YC by other rejects.  And I had another idea for a startup.  The biggest part of yCombinator's value proposition, for us, is the ability to work in a high-energy hacker environment, where we're continually getting feedback from our peers.  And that part is not limited to yCombinator: we could easily organize groups of startups together and have some friendly competition going.  We just need to group startups together.&lt;br /&gt;&lt;br /&gt;So, I'm taking a little diversion from Diffle (hopefully not more than a week or so) to work on RejectedByYC.com.  It'll have forums (which I've already setup), "demo groups" of about 10-12 startups, feature announcements, quick feedback, and karma.  The hope is that this'll provide motivation to many teams who were &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; able to get into yCombinator or other funding, letting us maintain a high level of energy even though we've been rejected.  Plus, by grouping them together, we may give them a brand advantage that lone startups don't have.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5106721948032887818?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5106721948032887818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5106721948032887818' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5106721948032887818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5106721948032887818'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/04/ycombinator.html' title='yCombinator'/><author><name>Jonathan Tang</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1972005369690104476</id><published>2007-04-12T15:21:00.000-05:00</published><updated>2008-01-21T01:49:31.900-05:00</updated><title type='text'>PIL</title><content type='html'>Lest I fall into the forget-about-updating trap again, I'm going to post an update about the past 5 days or so.  I'll enter these as 3 separate entries as they're really 3 separate topics, though in reality I'm typing them all out between compiles at work.&lt;br /&gt;&lt;br /&gt;On Saturday, I setup PIL, the Python Imaging Library.  We're using it for thumbnails.  Unfortunately, PIL is a real pill to install.  I must've spent close to a day on it, Googling for everything I could find and looking through several config files.&lt;br /&gt;&lt;br /&gt;In the end, my problems were due to 3 problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;PIL requires libjpeg to operate on JPEG files.  And the Debian package is not sufficient; it must be downloaded and built from source&lt;/li&gt;&lt;li&gt;libjpeg must be installed with the "make install-lib" command.  The standard make install doesn't cut it.&lt;/li&gt;&lt;li&gt;PIL's setup.py will tell you that it successfully installed JPEG support even when it didn't.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Unfortunately, problem #3 masked problem #2, which led to a long wild-goose chase.  I only found the problem when I tried a "python setup.py build_ext -i", which fails properly if libjpeg is not correctly installed.  It at least told me that the header files were missing, which led me to read libjpeg's README file more carefully and fix the problem.&lt;br /&gt;&lt;br /&gt;In my Googling, I found that many other people have had the same problem, and the PIL developers have been very unhelpful in resolving it.  So once I make this public and Google indexes it, perhaps it'll prove useful to folks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1972005369690104476?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1972005369690104476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1972005369690104476' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1972005369690104476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1972005369690104476'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/04/pil.html' title='PIL'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-1864087197070423517</id><published>2007-04-05T14:48:00.000-05:00</published><updated>2007-04-05T15:20:15.939-05:00</updated><title type='text'>Month's catch up</title><content type='html'>So, I haven't updated in a month.  I suppose that's good, since it means I've been working instead of writing about working.  Though I imagine it's rather frustrating for the readers.&lt;br /&gt;&lt;br /&gt;I won't even try to go over the features I've implemented.  Judging from the last entry, it includes, comments, comment threading, tabs/subpages for user and game pages, AJAX ratings, comment replies, private messaging, new sort orders, plenty of bugfixes, and probably some stuff I've forgotten.  I'd have to go over the Subversion logs to keep track of it all.&lt;br /&gt;&lt;br /&gt;There are two developments that I want to include, since they're not in the Subversion logs.&lt;br /&gt;&lt;br /&gt;We got our dedicated on March 13.  It's a bottom-of-the-line Celeron - no sense spending more money than we have to if it never takes off.  IIRC, Mike made the order from GoDaddy on a Tuesday, we had it by Thursday night, and that's when I started setting it up.  The default firewall installation blocked DNS, so we thought that the DNS hadn't propagated when it was really my own stupidity.&lt;br /&gt;&lt;br /&gt;Even before the domain worked, I started setting it up.  Made a few subdomains for dev tasks and setup Apache virtual hosts for them.  We're *only* using Apache for development &amp; administrative tasks; the main production server is Lighttpd with an SCGI connection to Python.  But I didn't want to figure out PHP/Perl/WebDAV for Lighttpd and I figured it'd be good to have our tools in a separate process for security/performance reasons anyway.&lt;br /&gt;&lt;br /&gt;Over the next couple days and the weekend, I setup user accounts, upgraded Python to 2.5 &amp; installed libraries, installed Lighttpd and configured it, configured flup and wrote a quick launch script, learned how to write /etc/init.d scripts to start everything, and basically got things working.  By the conference call on Sunday, we were mostly good.  I think I needed to do a couple tweaks to SCGI and flup to get the app running, and it wasn't until the next Wednesday that I installed monit.&lt;br /&gt;&lt;br /&gt;Speaking of which, there were a few useful utility programs we rely on heavily:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Pligg, for organizing all our links.  HOW-TOs, tutorials, documentation, 3rd-party download sites, potential game developers we want to approach, and competitors all go here.&lt;/li&gt;&lt;li&gt;MediaWiki, for documentation.  We aren't really using this yet.&lt;/li&gt;&lt;li&gt;AWStats, for web server statistics.  I was surprised how easy this was to setup.&lt;/li&gt;&lt;li&gt;Munin, for monitoring server health.  Ditto&lt;/li&gt;&lt;li&gt;Monit, for automatically rebooting services when they go down.&lt;/li&gt;&lt;/ol&gt;Those were all part of the setup process on Friday/Saturday/Sunday.&lt;br /&gt;&lt;br /&gt;The other interesting development was that we applied to yCombinator.  I had previously floated the idea, but we weren't terribly interested then.  However, many of our objections were answered by the ensuing blogosphere buzz (SFP applications are apparently a big deal in the startup world), so I asked my cofounders to give it a second look.  Thus followed about 4 days of scrambling to get all the information we needed to fill out the application.&lt;br /&gt;&lt;br /&gt;Then PG e-mailed us back and said we had too many weakly-committed founders, and probably too many founders in general.&lt;br /&gt;&lt;br /&gt;I had misinterpreted the deadline, so we had an extra day to revise our app.  We had an emergency conference call that night, which was probably one of the hardest and most awkward conversations I've ever had.  The three founders who were not willing to commit full-time to Diffle were cool about it, though, and we ended up deciding it was okay for me and Mike to apply as a duo, and adjusted equity shares appropriately.&lt;br /&gt;&lt;br /&gt;We're still waiting to hear back from yCombinator.  Obviously, I hope we get in, since they add a lot of value.  But we're going to go ahead with this anyway, even if we don't.  I want to see this product exist, and we can continue to do that even if yCombinator doesn't want to invest.&lt;br /&gt;&lt;br /&gt;Right now, Mike is working on the layout with Matt's help.  I just finished adding comment replies and logout, so I've got a few cleanup items left.  Then I want to move towards writing actual Flash games and starting on the game creation engine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-1864087197070423517?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/1864087197070423517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=1864087197070423517' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1864087197070423517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/1864087197070423517'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/04/months-catch-up.html' title='Month&apos;s catch up'/><author><name>Jonathan Tang</name><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-7763154005125408859</id><published>2007-03-01T11:16:00.000-05:00</published><updated>2007-03-01T11:23:45.943-05:00</updated><title type='text'>Database libraries</title><content type='html'>Monday - Wednesday was spent redoing the database access layer.  I'd been using web.py's built in database libraries, but that's not suitable for the production site, because it uses a global database connection.  If we need to move to multiple databases, it'll be a royal mess.&lt;br /&gt;&lt;br /&gt;I considered using SQLAlchemy and spent much of last week researching that, but IMHO it's overkill.  I don't need a full object/relational mapping layer; I'm quite happy with SQL and don't need to write my SQL statements in Python.  So I ended up writing a thin wrapper on top of raw DBAPI classes.  It basically provides convenience methods similar to PEAR DB for querying (using SQL), along with direct SQL generation for INSERT, UPDATE, and DELETE.&lt;br /&gt;&lt;br /&gt;Am very grateful for unit tests.  They let me change everything globally and let me know instantly where I'd broken things.  Just need to flesh them out; a couple pages don't yet have tests.&lt;br /&gt;&lt;br /&gt;This morning, I got a comment box to appear on the game page.  Wrote the database schema for comments on the subway.  I'll integrate it in and write the code when I get home.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-7763154005125408859?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/7763154005125408859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=7763154005125408859' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7763154005125408859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7763154005125408859'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/03/database-libraries.html' title='Database libraries'/><author><name>Jonathan Tang</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5517959052488813065</id><published>2007-02-25T12:32:00.000-05:00</published><updated>2007-02-25T12:33:01.967-05:00</updated><title type='text'>Game page</title><content type='html'>Got the game page working, and hit counters.  That didn't take long.  Still no comments, though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5517959052488813065?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5517959052488813065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5517959052488813065' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5517959052488813065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5517959052488813065'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/game-page.html' title='Game page'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-8351222128123317008</id><published>2007-02-25T09:59:00.000-05:00</published><updated>2007-02-25T10:24:20.590-05:00</updated><title type='text'>Last week's activity</title><content type='html'>A full week between posts.  Ah well, shows I've been spending the time hacking rather than blogging about it.&lt;br /&gt;&lt;br /&gt;Last week's conference call went well, despite not having something demoable.  Matt had lots of good logo choices, though he was going to keep working at it and see if he could come up with anything better.  I think it was last week that James finished the registration page layout.  And we had some incorporation &amp; decision-making stuff to talk about.&lt;br /&gt;&lt;br /&gt;When I left off, I was incorporating the mock layout into the real app.  That went smoothly - I just copied over the DreamWeaver HTML, CSS, and image files, replaced the content and login boxes with template vars, and it just worked.  It's horribly messy CSS - DreamWeaver uses absolute positioning for everything, so I'm eventually going to have to go through and redo the format with a sane box model.  But that'll wait till after the logo and final layout, since there will likely be further tweaks.  This is good enough for testing &amp; demos.&lt;br /&gt;&lt;br /&gt;I also had to change the formatting a little to get the login box to fit.  Not entirely satisfied with it; we'll likely have a space problem if we add OpenID.  But we can cross that bridge when we come to it too.&lt;br /&gt;&lt;br /&gt;When I got to the registration page, I realized that I really should figure out internationalization issues first.  So that was most of this week.  Started by simply trying to setup a null translation and load the resource bundle based on a database field; I finished that on Tuesday (yay for Monday being a holiday).  That didn't work when I tried to add actual messages, so I spent some time Googling around for gettext tutorials, didn't find any, and then finally looked through the Mailman source.  Fixed it on Thursday, just after Grey's Anatomy (I seem to get a lot done during that show.  Maybe it's because last week's episode had me wishing that they &lt;span style="font-style:italic;"&gt;had&lt;/span&gt; killed Meredith.)&lt;br /&gt;&lt;br /&gt;I started working on the validation libraries concurrently.  Wrote out the basic design on the Red Line Wednesday, then came home and typed most of it in on Wednesday night.  Added the unit tests on Friday, finished up the validators, then spent all day yesterday integrating it in with the registration form and debugging.  Seems to be working fairly well now.&lt;br /&gt;&lt;br /&gt;I also did some minor CSS tweaks so the registration and upload forms look relatively pretty now.&lt;br /&gt;&lt;br /&gt;Now I'm trying to finish the game page (instead of having it link directly to the SWF file), and hopefully get to comments.  Yeah, I said that last week, but i18n and validation intervened.  I'm glad that we're building a really solid app first, though, and then adding features.  It gives a much more realistic idea of the schedule, and we can always cut features for launch.&lt;br /&gt;&lt;br /&gt;The current plan is to launch with basic game uploading, commenting (threaded, with Markdown formatting), rating, and nothing else.  That'll hopefully be enough to keep visitors coming back, and then we can improve it rapidly, add features like studios and the game creation engine, and listen to user feedback.&lt;br /&gt;&lt;br /&gt;I'm thinking sometime around April for the date - if we can time it for spring break, that'd be great.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-8351222128123317008?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/8351222128123317008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=8351222128123317008' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8351222128123317008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/8351222128123317008'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/last-weeks-activity.html' title='Last week&apos;s activity'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5925656451220898743</id><published>2007-02-18T12:27:00.000-05:00</published><updated>2007-02-18T12:54:08.557-05:00</updated><title type='text'>Catching up on testing....</title><content type='html'>I've been delinquent about keeping up with this.  You'd think that with simple few-sentence updates, I'd remember to keep a log, but no.  I'll have to reconstruct much of the past week from memory.&lt;br /&gt;&lt;br /&gt;So, &lt;a href="http://diffle-history.blogspot.com/2007/02/vmware-emacs.html"&gt;when I left off&lt;/a&gt;, I was just getting Emacs running again with VMWare.  My next priority was testing.&lt;br /&gt;&lt;br /&gt;I setup a MakeFile with some really simple phony targets - one to clean out all the .pyc and ~ backup files, one to run the built-in server for development, and one to run all the unit tests.  I think this was Friday or Saturday a week ago.  I do remember that I had no demo for last Sunday's conference call - I was still working on testing and refactoring.&lt;br /&gt;&lt;br /&gt;Testing was a little tricky.  I had to figure out twill - I think that was mostly last weekend, and the week before last.  I'm beginning to love Python's dir() and help() functions - there's no complete API reference twill, but it has great docstrings.  From there, I had to integrate it into doctest (I punted on unittest because I really hate xUnit-style tests; they require so much boilerplate code that I find myself ignoring the unit tests anyway).  Never did get doctest.testfile() working; instead, I wrote a script to walk all the source dirs, turn the Python file into a module name, dynamically import it, get a reference to the module via globals().__dict__[modulename], and pass it to doctest.testmod().  I also wrote a twilltest helper module with some assertion functions that I wanted to be able to use for tests, and then added it to the doctest scope via extraglobs.  This was done throughout most of last week; I wrote the helper functions as I needed them for specific tests.&lt;br /&gt;&lt;br /&gt;After the meeting last Sunday, I spent the day coming up with usability personas.  I think they're a good thing to have; as we design new features, it's nice to be able to say "David needs this" or "Katie won't use the site if we can't do this."  They've already helped illuminate some conceptual muddiness.&lt;br /&gt;&lt;br /&gt;Last weekend, I also moved things around so that all controllers live in one directory in the www directory, and pulled lib (helper Python files) and templates (HTML) back to the top of the trunk.  The main entry point (main.py) and the unit testing script (runtests.py) were moved all the way to the top level.  Still not sure if this is the right organization; there will likely be further changes as the program grows. &lt;br /&gt;&lt;br /&gt;While I was at it, I had the request dispatcher auto-detect controller classes (through looking in www/controllers) and construct the URL list itself (through looking at the exported url_pattern global).  My svn log says this was last Tuesday, 2/13.  Python's dynamicity is fun.&lt;br /&gt;&lt;br /&gt;You would've thought that with Wednesday being a snow day, I would've gotten more done, but no.  I was working on stuff for my real job (from home) almost all day.  And then on Thursday I had to shovel.  Finally finished the unit testing framework on Thursday night, while watching Grey's Anatomy, and these last couple days have involved writing more tests for front page, logins, sessions, etc.&lt;br /&gt;&lt;br /&gt;Am working on integrating James's rough cut at a layout now.  If I get that done, I may take a crack at comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5925656451220898743?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5925656451220898743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5925656451220898743' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5925656451220898743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5925656451220898743'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/catching-up-on-testing.html' title='Catching up on testing....'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-7705005411693213890</id><published>2007-02-09T22:19:00.001-05:00</published><updated>2008-06-21T19:57:28.263-05:00</updated><title type='text'>VMWare &amp; Emacs</title><content type='html'>Got over my Emacs-can't-select-text-with-the-shift-key problem (I'm using CUA mode, otherwise Emacs wouldn't select text with the shift key anyway).  Turned out it was &lt;a href="http://www.vmware.com/community/thread.jspa?messageID=755"&gt;this issue&lt;/a&gt;, and I just had to disable the ATI Radeon taskbar icon.  Who'da thunk it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-7705005411693213890?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/7705005411693213890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=7705005411693213890' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7705005411693213890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/7705005411693213890'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/vmware-emacs.html' title='VMWare &amp; Emacs'/><author><name>Jonathan</name><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>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-5872167745091802249</id><published>2007-02-09T10:24:00.000-05:00</published><updated>2007-02-07T17:50:57.030-05:00</updated><title type='text'>Testing, testing</title><content type='html'>Didn't get nearly as much done this past couple days as I hoped.  I wrote some simple Twill scripts and tried it out from the interactive interpreter.  Read up some on doctest and unittest - I already use the former, but really dislike the latter because it's a jUnit-style framework (some other time, I'll write up a blog post about why that sucks).  Also installed BicycleRepairMan, PyChecker, and some additional Emacs modes, though I haven't tried them out yet.  &lt;br /&gt;&lt;br /&gt;I also had to deal with some Windows idiocy and re-copy my VMWare virtual disk because VMWare has trouble when the disk file is owned by some other Windows user.  I had created the VM initially as AMHERST/jdtang - yes, 2 years after graduation, my computer still thinks I was on the AMHERST domain because Windows apparently caches logins (good thing, too, otherwise it would break when I went home).  After wiping my computer, no more AMHERST for me, so I created a local account that had trouble writing to the logs and virtual disks created by the domain account.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-5872167745091802249?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/5872167745091802249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=5872167745091802249' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5872167745091802249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/5872167745091802249'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/testing-testing.html' title='Testing, testing'/><author><name>Jonathan</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3815850801059903543.post-617493793276729870</id><published>2007-02-07T17:20:00.003-05:00</published><updated>2008-06-22T08:25:48.095-05:00</updated><title type='text'>Intro post</title><content type='html'>[Original blog description: "For posterity's sake, this records the very early days of Diffle Inc. (or so we think it'll be called) and its Flash-based social games site.  It's intended to be private, at least if/until Diffle manages to become successful."]&lt;br /&gt;&lt;br /&gt;I want to create this blog for a couple of reasons:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;So I can better estimate how long new features will take.  It's amazing how easily memories of implementing some feature get distorted.&lt;/li&gt;&lt;li&gt;Because I find it fascinating reading about the early days of businesses, particularly businesses that later grow enormously successful.  I can't guarantee this'll be enormously successful (I rather doubt it, actually), but just in case, I'd like to record things.&lt;/li&gt;&lt;/ol&gt;This is really more of a journal than a blog, since it's intended to be private unless Diffle (or whatever we decide to call it) gets big.  I've got a bunch of reasons for that: I don't want to get in trouble with my present employer, I don't want to set up expectations that we can't meet, I don't want to give away secrets that'll help potential competitors.  But mostly, I just think it's premature and a distraction from actually getting the site implemented.  So this'll have entries on current events, but it's not really intended for a readership.  Expect some chop.&lt;br /&gt;&lt;br /&gt;Anyway, the story so far:&lt;br /&gt;&lt;br /&gt;Diffle is supposed to be a website for social networking based on simple, 2D flash games.  Kinda like a cross between Yahoo!Games, MySpace, and Fanfiction.Net.  We've actually got two names under consideration: Diffle and GameClay.  The current plan is to launch with Diffle as a pure social networking site centered around games.  If it takes off, we add GameClay as an additional feature.  If it doesn't, we abandon the diffle.com site and rebrand as gameclay.com with the additional game-creation features.&lt;br /&gt;&lt;br /&gt;My involvement is 2.5 weeks old at this point.  The site initially started with Mike's summer internship, researching companies in the space, and his getting together with James.  Andrew was brought on board for finance/legal, and Matt for art &amp;amp; graphic design.  They brought Xin on board as their programmer around late October or early November.&lt;br /&gt;&lt;br /&gt;That was the status when I saw Mike at Homecoming.  We chatted a bit, he asked me if I wanted to do some Flash development or front-end work, but it would've been a contract position rather than a founder stake (with 5 co-founders, the equity is already spread pretty thinly).  Besides, I don't know Flash.&lt;br /&gt;&lt;br /&gt;Fast forward to late December.  Xin's on a student visa, so he finds out that he can't co-found a startup without putting his visa status at risk.  There's a mad scramble to find another programmer.  As I understand it, there were a few people ahead of me on the list, but none of them wanted to do it (hey, 4 guys a year and a half out of college starting a business in a hot sector, I'd be skeptical too).&lt;br /&gt;&lt;br /&gt;Mike contacted me over AIM on Friday, 1/19.  He e-mailed me the business plan, and I took a look at it as soon as I got home from work.  It looked very exciting; there's a potentially big (though risky) opportunity here, and it was exactly the sort of project that I've wanted to do since college.  Mike and I had a good conversation on Saturday morning, we both were very enthusiastic, and so I was brought on board as the programmer.  I spent most of Sunday setting up my development environment - Linux, Python, MySQL, assorted libraries.  Luckily, I have a spare Debian VMWare image for just such purposes.&lt;br /&gt;&lt;br /&gt;First Skype conference was on Monday night, and I got a quick introduction to what had been done already (a lot on the design/conceptual side, essentially nothing on the technical side) and where we were going.  Spent most of the rest of the week learning web.py.  I also got permission from Tosin (NOTE's current head at Amherst) to use one of the NOTE servers for prototyping/demo and install whatever I wanted on it.  For the next week's conference (1/28), I had a really simple demo with a barebones front page and registration form up.&lt;br /&gt;&lt;br /&gt;The week after that, I got a lot more done featurewise.  Finished most of sessions and authentication during the workweek - I usually managed to put in a half hour or so before work while eating breakfast and an hour or two after work.  Plus, if there are sticky spots, I write 'em out on paper and pencil on the Red Line (much of session handling was done in a day or two in this manner).  The demo on 2/4 included sessions, logins, the ability to upload games, games appearing on the front page, and a simple user page.  Uploading was done all on Saturday, and having them show up was Sunday morning.  Still far from complete functionality, but good progress.&lt;br /&gt;&lt;br /&gt;I said that I likely won't have as much done for next week, where "not as much" may mean "nothing" featurewise.  Instead, I'm cleaning up the nascent code base and investing in some infrastructure requirements.  I setup a Subversion repository on Monday night after I finished watching 24, then posted to web.py for testing suggestions and started checking out twill yesterday.  I'm hoping to write some tests tonight, establish a framework for testing, and do a one-step build process that handles pychecker and all our tests.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3815850801059903543-617493793276729870?l=diffle-history.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://diffle-history.blogspot.com/feeds/617493793276729870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3815850801059903543&amp;postID=617493793276729870' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/617493793276729870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3815850801059903543/posts/default/617493793276729870'/><link rel='alternate' type='text/html' href='http://diffle-history.blogspot.com/2007/02/intro-post.html' title='Intro post'/><author><name>Jonathan</name><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>2</thr:total></entry></feed>
