Archive for the ‘design’ tag
I would like to:
- To write graphics and visualization code
- To author elegant APIs and code
- To work in an area requiring both technical and aesthetic understanding
- To have my daily contribution significantly impact the success or failure of a project
- To constantly teach and learn from others inspired by similar goals
- To do the above and somehow generate enough income to live comfortably
As I work for a while doing some moderately interesting work, I’m trying to figure out how to make this happen. I do not know exactly how to make this happen, but I know I have a lot of work to do before I will wake to find myself in a position like the above.
Seeing an awesome blog post like over at Codeflow demonstrating WebGL GPU Landscaping and Erosion, reminds me in both inspiring and daunting ways how much I need to do to make my work into the kind of work that I admire.
I know I need to do…
If I wish to work on graphics and visualization, I need to produce more impressive results. I need to do this visibly. That, in practical terms, means using the web. I do not want to abandon LxEngine by any means – but I think I need to start working with WebGL and produce immediately demonstrable results. No one is willing to download something they don’t already want these days.
If I wish to work in an area requiring both technical and aesthetic understanding, I need to improve the design of this site. This site suffers seriously from programmer design. It needs proper design: as in a studied design, not merely “something that I thought looked okay.” I cringe in imagining a professional designer’s feedback on this blog design. It is currently the result of a programmer learning WordPress, CSS, and HTML and experimenting directly on the site. I need to redesign this blog theme. The wiki could use some work as well.
If I want to write elegant APIs and code, that means I need to write complete code. I need to aim for smaller projects and demonstrations. This is a simple reality if I am working on my own and demand high-quality from myself. Also, if elegant code is an objective of mine, that unfortunately means I need a degree of control over my code: a degree of control that might not always be available in a large commercial company. Again, if that is truly an objective of mine, I may need to aim for a smaller scope.
If I want my daily contribution to count, I need to find work others have not done before. If there are known solutions, then my work is eminently replaceable. I need to be more unique. I also need to work hard.
If I want to to teach and learn from others, I need to more actively engage in the graphics community: forums, blogs, twitter, and – I daresay – the real world. Some of the small projects might demonstrate solutions to problems posted on forums, act as plug-ins to popular open source projects.
If I want to make income doing this, I need to market myself better. This means I need to create a front-page that concisely and immediately communicates what I can offer. I have one in the works, but it has a long way to go. I will also need to think about the utility of the projects I engage in. I need to produce stuff that others find compelling as well as myself.
I’m not sure what the summary of this post should be exactly: I know in general what I would like to be doing and am realizing I need to get serious about finding what in particular I need to be doing to get there. There’s a lot of work ahead of me.
As I noted, I’ve been spending the last while doing a bit more web-oriented programming. It’s been fun dabbling a bit more towards the design-side of things (note: I do realize that a couple weeks playing with CSS does not qualify me as being a designer!). In any case, the low-budget local projects have given me a chance to work in areas where I certainly have less expertise. For example: choosing a good type face for a site and/or section of a site.
Being an engineer at heart, I naturally built a tool to help with the selection process. I know it’s not a unique tool (there are plenty out there like this one, though likely better than this one) but it also did not require much effort.
Without further ado, here’s the link to a simple JQuery-based tool for previewing various font styles:
I read an interesting article a little over a week ago, called “”Think by Building / Build to Answer Questions” on hobbygamedev.com. I believe I understood the crux of the author’s point and agreed with his statements in general; however, if I were to task to writing a similar article or passing along the article to novice developer, I might present the following points:
It’s okay to throw away code
I believe this was a key point of the original article. You, as a coder – especially in a small hobby-coding environment – are never going to know ‘exactly’ how everything will work in advance. There’s simply too much complexity to fit into one person’s head at once. In the context of a hobby project (where you don’t have a black-box test team), trying to record all those individual details into a specification first isn’t necessarily worthwhile either: that same time could be spent simply coding all those details!
Another key point of the article was that often is an unhelpful sense that once code is written, it can’t be discarded. As a coder, it’s important to get past that feeling when it is encountered. If you’re at least considering that rewriting a section of code might be a good idea, then that implies there’s a good chance that the code is not satisfying some requirement you now see. Don’t expect all code to be perfect the first time it is written: see the prior paragraph about it being impossible to know all the details in advanced.
The article also makes a good point experimenting with cost is far lower cost than experimenting with bridge building. Remember the low cost and don’t be afraid to discard something that doesn’t work.
In other words, as you code, you learn. As you learn, you find mistakes in your previous thinking (that happens in all forms of learning, not just coding). It’s okay to throw away old code in order to improve the overall code base.
Don’t expect to know all the details in advance, but do use proven, general designs and design patterns
The original article talks about guitarists strumming their guitars, chefs cooking new recipes, and painters painting the canvas as a means to “build.” However, this is only one aspect of how an artists works. Painters most certainly study composition and color theory, chefs visit gourmet restaurants as well as know classical recipes, and guitarists certainly have learn at least a minimal amount about chords before diving too seriously into song writing. I highly doubt the author was in any way denying this, but he did not put much emphasis that all the study and preparation that happens to accompany the more freeform invention stage that takes place while actually participating in the art.
Good code likewise requires preparation (guitarists know the chords, programmers know the programming language) and design (painters know visual composition, programmers know design patterns). Heads down coding will help test designs and refine them. Heads down coding does not however do well as well to invent new concepts and patterns. Heads down coding is good for working out details, but less helpful on working out the big picture.
There’s a definite line between “discovering ideas by building” and “testing ideas by building.” The latter works very well – there’s nothing like actually trying something to prove if it will work, but the former is simply not an efficient means of getting things done. If you think you have a fantastic idea on how to sort a set of numbers – go ahead and code it. See if it works. That’ll expose you to all the details. But if you want to sort a set of numbers, sitting down to code until you “think up” how to do it…well, your time could be better spent by utilizing the work of decades of study by others in how to sort numbers. Be aware of qsort, std::sort<>, bubble sorts, radix sorts, etc. and then test which works best for you.
Of course, “sorting” is an extreme example and in reality it’s a gray line between what is a “detail” and what is a “design” and what amounts to “discovery” versus “testing”; however, I think it’s important to remember that coding in and of itself is far better at refining what you already know rather than expanding the realm of what you know.
Dependencies, dependencies, dependencies
The original article points out that code is cheaper than bridge building materials and while this is correct, it can be painful to rip out a chunk of code in a complex project as it may break everything that depends on it. That’s why there are principles like the separation of interface and implementation. That’s why there concepts like Adapter and Decorator design patterns.
A good design, made in advance, allows the details to change more easily. A good initial design has a symbiotic relationship that actually allows you to “think by building” more easily. So as a general rule, make a component depend on exactly what it needs to depend on to meet its objective and nothing more:
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” — Antoine de Saint-Exupery
Do the same with your code. Use good, clean, proven, minimal designs and make the rest just details.
Keep a sketchbook handy
The crux of this post is a common sense point: keep a balance.
- Plan and prepare in advance using a good, proven initial design. The better the initial interface, the more it will allow you to experiment and refine more easily.
- Experiment and refine actively. It is an instructive process and there’s no more certain way to test out an idea to see if it really will work.
As a practical means of employing this strategy, make sure that every type of code has its place. A painter has large expensive canvases for the final work as well as scraps of discarded paper for doodling on. Both are real parts of his tool set. Code should operate the same way. Have a place to experiment with code as well as a place for the production-level code – and, have a migration path between the two. For example:
- Use git branches for experimental features
- Allow your developers (yourself included) to miss deadlines because an idea didn’t work
- Account for the last bullet point in your project schedule (otherwise, you’re not really allowing it…)
- Ensure your main application supports extensions and plug-ins for new features that might not ship
- Use unit tests to testing new experimental implementations of existing interfaces
- Have a “Labs” area for prototype code
All in all, design and implementation are a balance, so actively account for that in your projects.