tag:blogger.com,1999:blog-38158508010599035432024-03-15T03:24:52.285-05:00Diary of a Failed StartupThis 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.Jonathanhttp://www.blogger.com/profile/05399629264608295968noreply@blogger.comBlogger56125tag:blogger.com,1999:blog-3815850801059903543.post-43583760475447082692008-12-08T18:53:00.004-05:002008-12-09T01:44:39.445-05:00AftermathIt'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.<br /><br /><span style="font-weight: bold;">Job Hunt</span><br /><br />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.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">Immediate Aftermath</span><br /><br />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.<br /><br />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.<br /><br />For anyone faced with winding down a company, I'd <span style="font-style: italic;">highly</span> 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.<br /><br />The corollary to that is to wind up your startup <span style="font-style: italic;">before</span> 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.<br /><br />Anyway, I ended up developing a <a href="http://eve-language.blogspot.com/">programming language</a> 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.<br /><br />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.<br /><br />I also spent a lot of this time stripping off pieces of GameClay, cleaning them up, writing docs, and <a href="http://jonathan.tang.name/code/">open-sourcing</a> them. This often took longer than writing the initial code.<br /><br />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.<br /><br />I didn't decide what general direction I wanted to go until <span style="font-style: italic;">very</span> 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.<br /><br />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 <span style="font-style: italic;">fun</span> 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.<br /><br /><span style="font-weight: bold;"><span style="font-weight: bold;">Some additional lessons</span></span><br /><br />I keep thinking of other things I wish I'd said in the <a href="http://diffle-history.blogspot.com/2008/06/postmortem.html">postmortem</a> 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.<br /><br />The big one: startups are <span style="font-style: italic;">out there</span>, not <span style="font-style: italic;">in your hea<span style="font-style: italic;">d</span></span>. 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 <span style="font-style: italic;">spot on</span> (and almost no ideas are), this is a recipe for failure.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">Conclusion</span><br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com101tag:blogger.com,1999:blog-3815850801059903543.post-9267719876449305642008-06-20T20:33:00.008-05:002008-06-22T09:14:39.204-05:00PostmortemSo, 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.<br /><br /><span style="font-weight: bold;">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.</span><span><br /><br />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 <span style="font-style: italic;">application</span> 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.<br /><br />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.<br /><br />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 <span style="font-style: italic;">something</span> well.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">It's a marathon, but it's a marathon made of sprints</span><br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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 <span style="font-style: italic;">hard</span>, and a lot of my time was spent dealing with problems related to this.<br /><br /><span style="font-weight: bold;">Initial conditions matter. A lot.</span><br /><br />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.<br /><br />The initial idea <span style="font-style: italic;">does</span> change, and it's almost certainly wrong. The thing is, the initial idea determines <span style="font-style: italic;">how</span> 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.<br /><br />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 & word games, so we were positioned wrong from the start.<br /><br />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 <span style="font-style: italic;">don't</span> 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.<br /><br />All this is not suggesting that you overthink every possible decision at the beginning of the project and make sure you have the <span style="font-style: italic;">perfect</span> 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.)<br /><br /><span style="font-weight: bold;">Developing in a vacuum never works.</span><br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">Beware the chicken and the egg.</span><br /><br />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.<br /><br />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.<br /><br />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 <span style="font-style: italic;">get out there and put it in front of lots of other people.</span> It's that last point where we failed: we just kinda built the product, launched it, and let it die.<br /><br />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.<br /><br /><span style="font-weight: bold;">Prototype any 3rd-party libraries that you'll be depending upon, <span style="font-style: italic;">before</span> you base your product on them.</span><br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">If you're doing anything other than building your project and getting users, it's premature.</span><br /><br />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.<br /><br />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.<br /><br />Some things we did well on this front:<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">The product will take longer than you expect. Design for the long-term.</span><span><br /><br />I need to put this together with the last point, because otherwise I know someone will misinterpret one or both.<br /><br />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:<br /><br />Do anything you possibly can to avoid bugs.<br /><br />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.<br /><br />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 <span style="font-style: italic;">loss</span>. 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.<br /><br /><span style="font-weight: bold;">People have an incentive not to crush your dreams. Take everything they say with a grain of salt.</span><br /><br />When we <span style="font-style: italic;">did</span> 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.)<br /><br />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.<br /><br />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.<br /><br />This of course presupposes that you <span style="font-style: italic;">want</span> 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.<br /><br />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 <span style="font-style: italic;">really</span> 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.<br /><br /><span style="font-weight: bold;">Know your limitations.</span><br /><br />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."<br /><br />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.<br /><br />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 & 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 <span style="font-style: italic;">only</span> 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.<br /><br />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.<br /><br />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.<br /><br /><span style="font-weight: bold;">Conclusion</span><span><br /><br />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 <span style="font-style: italic;">why</span> I'm giving up:<br /></span></span></span><ol><li>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.</li><li>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.</li><li>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.</li><li>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.</li></ol>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 <span style="font-style: italic;">this</span> startup. I'm a little sad about that, but I have no regrets about having started it.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com260tag:blogger.com,1999:blog-3815850801059903543.post-32555846376198734902008-06-20T13:17:00.003-05:002008-06-21T18:27:18.970-05:00The end, I thinkDidn'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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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 <a href="http://eve-language.blogspot.com/">programming language</a> 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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com5tag:blogger.com,1999:blog-3815850801059903543.post-86561108289499261772008-06-11T10:15:00.003-05:002008-06-21T18:25:50.942-05:00UpdatesWoah, 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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />I think we may be within a month or a month and a half of launch.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com9tag:blogger.com,1999:blog-3815850801059903543.post-3329596999760918992008-04-28T12:22:00.002-05:002008-04-28T12:29:39.465-05:00Performance reality checkDoing 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.<br /><br />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.<br /><br />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...Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-68817607887155015092008-04-25T17:23:00.002-05:002008-04-25T17:42:15.721-05:00Productive couple daysDid 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.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-23217733679868661132008-04-21T11:35:00.000-05:002008-04-21T12:01:54.517-05:00The problem with the ideaJust sent this to the project mailing list for comment:<br /><br />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:<br /><br />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.<br /><br />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 & graphs & 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.<br /><br />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...<br /><br />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 & patterns of movement."<br /><br />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 & word games more than arcade shooters and such.<br /><br />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".<br /><br />So, I guess the next question is what do we do now? I guess I've got 3 main options:<br /><br />1.) Push forwards until launch, then add whatever features are necessary to make a compelling product afterwards.<br /><br />2.) Step back and try a different tack, finding another entry point into the casual game creation market.<br /><br />3.) Quit and take a job at FriendFeed.<br /><br />#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.<br /><br />There're a couple options for #2 that I want to bounce off people:<br /><br />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.<br /><br />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 -> multiplayer game -> customizable multiplayer game -> 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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com3tag:blogger.com,1999:blog-3815850801059903543.post-11771349439624285342008-04-17T01:38:00.003-05:002008-06-21T18:29:30.539-05:00More bad newsGot 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).<br /><br />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.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com3tag:blogger.com,1999:blog-3815850801059903543.post-28100379404178533022008-04-01T15:39:00.003-05:002008-06-22T09:11:56.168-05:00More founder updatesJust 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 <span style="font-style: italic;">really</span> small. Most of my classmates are becoming lawyers or financiers.<br /><br />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...<br /><br />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.<br /><br />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).Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-27803557612225384082008-03-28T21:06:00.002-05:002008-03-28T22:00:02.469-05:00The end of a cofounderMike 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.<br /><br />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.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-53012529820591181952008-03-17T22:08:00.002-05:002008-03-17T22:44:25.454-05:00MisgivingsI'm reading <span style="font-style: italic;">Dreaming in Code,</span> the history of the Chandler project, and there's an ominous quote from Linus Torvalds:<br /><blockquote><br />Nobody should start to undertake a large project. You start with a small <span style="font-style: italic;">trivial</span> 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.<br /></blockquote><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-9231787835130644772008-03-14T12:15:00.003-05:002008-03-14T13:44:09.526-05:00First archetypesSo, 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.<br /><br />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.<br /><br />Been avoiding it by watching basically all of Medium Season 1 & 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.<br /><br />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 & 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 & friction (making them parameters of the collision and not separate actions, for instance). And some aspects - like victory conditions - need a lot more attention.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-38506428453140010302008-03-03T15:42:00.002-05:002008-03-03T15:55:22.779-05:00The game compilerJust 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 & 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.<br /><br />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 <span style="font-style: italic;">get there.</span><br /><br />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 <span style="font-style: italic;">release something</span>. 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.<br /><br />Actually, we <span style="font-style: italic;">did</span> 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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-85784548296363285272008-02-22T00:51:00.002-05:002008-02-22T02:03:09.248-05:00Abstract vs. Opaque data typesSo, 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.<br /><br />First, definitions. An <span style="font-style: italic;">abstract</span> 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 <span style="font-style: italic;">opaque</span> 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). <br /><br />Some languages - like Arc, JavaScript or pure Scheme - provide <span style="font-style: italic;">only</span> abstract data types, and you need to fake opaque types with conventions. Other languages - like Java - provide <span style="font-style: italic;">only</span> 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.<br /><br />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.<br /><br />In production code, I've found opaque types to be <span style="font-style: italic;">generally</span> better, because they provide additional contractual guarantees that are really important when you're building stuff on top of these classes. You don't <span style="font-style: italic;">want</span> 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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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).Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-19611153776644038002008-02-22T00:32:00.003-05:002008-02-22T00:51:48.751-05:00Arc, offers, and hiccupsIt'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:<br /><br />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.<br /><br />'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.<br /><br />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. <br /><br />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.<br /><br />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.<br /><br />I'll do a separate post with the current technical hiccup that's been stalling me, for the last few hours at least.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com3tag:blogger.com,1999:blog-3815850801059903543.post-71945417044529570392008-01-31T12:30:00.001-05:002008-01-31T12:42:32.349-05:00InsanityLet 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.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com3tag:blogger.com,1999:blog-3815850801059903543.post-38999765977273435842008-01-17T12:16:00.000-05:002008-01-17T13:00:34.687-05:00Editor widgets and recessionsI 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.<br /><br />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.<br /><br />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...<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-34346817637022277022007-12-29T16:37:00.001-05:002008-06-21T08:44:55.769-05:00Breaking things upThe 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 & 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.<br /><br />But there's another option - I could <span style="font-style: italic;">make</span> 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 & publish games and yet don't need Pylons installed.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-26952200661488464072007-12-27T21:08:00.001-05:002008-06-21T18:45:24.285-05:00Pylons and DjangoThinking about switching the webapp portions of GameClay from Pylons to Django. This would be our third framework (web.py -> Pylons, Pylons -> 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.<br /><br />Here's a list of the various aspects and advantages & disadvantages of the frameworks:<br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Templates</span></span><br /><br />For Pylons, I'd stick with the default of Mako. Django comes with its own templating language, but it's not terribly hard to <a href="http://www.djangosnippets.org/snippets/97/">swap it out</a>. 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.<br /><br />Advantages for Pylons:<br /><ul><li>I don't have to rewrite our existing Mako templates</li><li>Mako is significantly more powerful than Django, with arbitrary expressions, defs, template inheritance (beyond layouts)</li><li>Mako filters get pulled from the template namespace automatically, which is a useful convenience when using potentially lots of filters</li><li>Same template system for website and game compiler</li><li>I can extend it with defs, in the template, without needing to write a separate Python module to write new tags<br /></li></ul>Advantages for Django:<br /><ul><li>I like the syntax better; it seems cleaner and easier to remember</li><li>Filters can take arguments; useful for things like indent()</li><li>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.<br /></li></ul><span style="font-weight: bold;"><span style="font-size:130%;">Models</span></span><br /><br />For Pylons, I'd use our custom Diffle DB database wrapper. For Django, I'd use its ORM.<br /><br />Advantages for Pylons:<br /><ul><li>Simpler; I know SQL already, don't need to learn a custom model definition language</li><li>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.</li><li>Gives finer-grained control over queries; I can often avoid some extraneous SELECT or UPDATE statements that Django's ORM adds.</li><li>Supports multi-column primary keys, something I've found pretty useful in past DB models.<br /></li></ul>Advantages for Django:<br /><ul><li>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).<br /></li><li>The admin interface is <span style="font-style: italic;">very</span> 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.)</li></ul><span style="font-weight: bold;"><span style="font-size:130%;">Controllers</span></span><br />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 <span style="font-style: italic;">really well</span> (I don't, yet).</span></span><br /><br />Advantages for Pylons:<br /><ul><li>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.)</li><li>Provides an easy way to attach data to controllers, like a database or mogile connection</li><li>Routes syntax is a little cleaner and more flexible than Django's URL-based dispatching.<br /></li></ul>Advantages for Django:<br /><ul><li>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.</li><li>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.</li><li>More explicit. Less to keep in mind.</li><li>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.</li><li>Can be decorated. Django provides a bunch of useful decorators, like @login_required.</li></ul>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<br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Sessions/Login/Registration</span></span><br />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.<br /><br />Advantages for Pylons:<br /><ul><li>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.</li><li>Integrates easily with the rest of the app, eg. templates and other controllers<br /></li></ul>Advantages for Django:<br /><ul><li>Provides usable default controllers for login, logout, and registration</li><li>User objects integrated with request; no need to explicitly check for login<br /></li><li>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.</li><li>Handles details like tamper-proof sessions, hashing, generating unique sessions, etc. transparently</li><li>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</li></ul><br /><br /><span style="font-weight: bold;"><span style="font-size:130%;">Other goodies<br /></span></span><br />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:<br /><br />Advantages of Django:<br /><ul><li>CSRF detection. We need to add this to all our forms otherwise; this is pretty handy middleware.</li><li>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.</li><li>Syndication feeds. There are Python libraries to do this, but the contrib app is likely easier to use</li></ul><br /><br /><span style="font-weight: bold;"><span style="font-size:130%;">Configuration, Packaging, and Testing</span></span><br />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.<br /><br />Advantages for Pylons:<br /></span><ol><li>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.]</li><li>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.</li><li>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.</li></ol>Advantages for Django:<br /><ul><li>Using a Python module as a config file keeps everything Pythonic, and gives some added flexibility</li><li>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.</li></ul>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 & dirty solution so they could go on to other things.<br /><span style="font-weight: bold;"><span style="font-size:130%;">Other reviews<br /></span></span><br />http://pythonmag.blogspot.com/2006/02/pylons-vs-turbogears.html<br />http://jesusphreak.infogami.com/blog/why_django<br />http://jesusphreak.infogami.com/blog/vrp1<br />http://www.cmlenz.net/blog/2006/08/the_python_web_.htmlJonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com11tag:blogger.com,1999:blog-3815850801059903543.post-50052087444437958742007-12-22T18:53:00.000-05:002007-12-22T18:57:17.693-05:00Unit testingFinally 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.<br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-60454367318116368682007-12-17T00:27:00.000-05:002007-12-17T00:56:28.607-05:00Mental CenteringI'm feeling like my mental center of gravity has been shifting more towards Diffle over the past 2-3 weeks. I remember <a href="http://diffle-history.blogspot.com/2007/10/slow-going.html">back in October</a> 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.<br /><br />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.<br /><br />Some notes on the issues in the last blog posting, so I know why I made certain decisions:<br /><ol><li>scheme2js was rejected because:</li><ol><li>It can't call out to arbitrary JavaScript functions; they have to be declared, in a way I couldn't figure out</li><li>It doesn't generate readable code at all - everything is temps, and it's like it's machine code.</li><li>I don't think there's any way I can get it working to generate MTASC code.</li></ol><li>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.<br /></li><li>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 & replace.</li><li>Leaning towards invoking the compiler via AJAX for the editor issue, though I still need to see how it works in practice.</li><li>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.</li><li>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.</li><li>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.</li><li>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.<br /></li></ol>Next steps are importing games into Mogile and building the editor. I expect some fun surprises with the editor.<br /><br />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:<br /><ol><li>Working on the editor, found that I couldn't edit trajectories and have them immediately applied to the game.</li><li>Fix would require that the editor have knowledge of individual game archetypes, which would introduce too much complexity.</li><li>Dropped the concept of game archetypes with special-cased code.</li><li>Because of this, the base game structure needs to have many more options.</li><li>This changes the primary data structure we're storing games as</li><li>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.<br /></li><li>Which means we might as well rewrite everything.</li></ol>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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com2tag:blogger.com,1999:blog-3815850801059903543.post-64740850379932099262007-12-07T21:32:00.000-05:002007-12-07T22:10:29.871-05:00RewritesBit 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.<br /><br />No matter how many times I make this mistake, I always seem to make it once more...<br /><br />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.<br /><br />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:<br /><ol><li>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.<br /></li><li>Canvas tag in general. Nobody seems to use it, but it may be pretty useful for what we're doing.</li><li>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.</li></ol>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:<br /><ol><li>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.</li><li>Duplicate the compiler in JavaScript, then eval the resulting function string and place it in the appropriate event handler. Same issues</li><li>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.</li></ol>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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-13276754252023832572007-12-04T21:09:00.000-05:002007-12-04T21:31:47.358-05:00PlatformsX-posted from a planWorld entry:<br /><p><br />I just followed a link to a <a href="http://worsethanfailure.com/Articles/The_Inner-Platform_Effect.aspx">Worse Than Failure</a> 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.<br /></p><p><br />Maybe it was a good thing that I left.<br /></p><p><br />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.<br /></p><p><br />Note to people who are thinking of starting a software company: do <i>not</i> 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.<br /></p><p><br />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.</p>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.<br /><br />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?"<br /><br />So I ditched the idea entirely.<br /><br />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.<br /><br />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 <span style="font-style: italic;">so many</span> 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?Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-44461260743343617072007-11-14T12:26:00.000-05:002007-11-14T12:44:33.782-05:00JavaScript, how I loathe theeRandom 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.<br /><br />Of course, I knew this already (<a href="http://halogen.note.amherst.edu/~jdtang/scheme_in_48/tutorial/overview.html">yay Haskell</a>), 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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com1tag:blogger.com,1999:blog-3815850801059903543.post-67792396907484982962007-11-12T16:01:00.000-05:002007-11-12T17:11:56.144-05:00Widgets done, integrating themAbout 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 & 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.<br /><br />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. <br /><br />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.<br /><br />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.Jonathan Tanghttp://www.blogger.com/profile/06932672178552206935noreply@blogger.com3