life update: art, proto{cols',',types}
Yup, it's happening again. Now it's pgame.
(Philosophy) Game development tools... Why games? Why development tools?
So the past year has been quite inspiring in philosophical terms. I realized that my life trajectory so far (within the realm of 'coding'-like activities) is I started playing games, then found making games more fun, then I realized making game-development tools is more fun. :) Starting with Game Maker then going through object models, serialization and stuff like that, I've found a few things to be important (some of these correspond to the principles outlined in the cgame paper or the poster, experimented with in a Ludum Dare game I made with it):
- save/load: Users often want to save/load games at any point, and your game shouldn't need too much to implement this. But not just that, a good way to build a level is to serialize the live level. So many other things are nice with serialization (see the cgame paper for more). We want it to be automatic for all objects, and in fact the manual specification should be for exceptions to the rule.
- live property editing: Allows quicker debugging and experimentation with ideas.
- live functionality editing: Editing 'code.' For same reason as live property editing.
- a principle of abstraction that supports the above: The above points should extend not just to built-in elements, but to anything the user can come up with and make using your tool. Ever. Any new logic the user writes, any new data types, and in a way that applies to the problem at hand--for example, some numbers are better specified in the editor visually, like a direction to face (check out Pharo's inspectors).
The last one is the tough one. For cgame, the principle of abstraction was an "entity-system" model.
Over time I've seen different ideas. C++/Java with class-style object orientation where classes are conflated with (possibly 'static') types (to skip this conflation, check out Smalltalk). More proper static typing a la Haskell but also functional things and the confluence of the two into monads (traditional Haskell IO) or streams (like Elm) (arguably one reducible to the other but reducability isn't sufficient). With functional I realized that this is one reason games are interesting: they are highly "current state" and "event based." You react to input events from the player, but even without such input things go crazy with AI enemies fighting each other or such. Implementing a compiler means implementing a function of type SourceodeA -> Either Error SourcecodeB
--a compiler is a transformation, and 'functional' is nice for writing those. What function is the game? Sorta hard. 'Functional relational programming' is a nice thing to check out here, where the model in a functional reactive model becomes a relational database, ensuring same-time constraints along with across-time constraints, using a mix of declarative/logic/SQLy and functional stuff. More resources on this: one, two, three.
Another reason games are interesting is that we are trying to build an aesthetic end product. It's not judged simply by "it's 5% faster" but "hey so I played this thing and I guess it's kinda sorta fun but like it depends on taste." So you want that immediate artist-artwork feedback loop you have when painting on an easel without a blindfold on or playing drums without earplugs in. Let's make games with the blindfold off.
Getting a little abstract there. But yeah that connects, I think, with the live coding point. I'd go as far as saying static typing is actually a hindrance to such right-brained activity. I'd rather work on the game proceed in cycles of right-brained 'creativity' (live coding with everything late-bound) followed by more left-brained 'crystallization' (most testing / solidifying activity, with static types helping here). Much like the cycle of paradigms in Kuhn's The Structure of Scientific Revolutions, and the right-brained crystallization periods along the lines of the 'metaphors' in Bohm and Peat's Science, Order, and Creativity, except applied to a much localized and quicker process in the game creator(s) mind(s) rather than that in the Gaia behind generations of scientists. You can go pretty far down this rabbit hole, other reads including Nietzsche's works (esp. The Gay Science, Beyond Good and Evil) and Robert Anton Wilson's Prometheus Rising. To live code with ultimate freedom you need to be able to change a thing's type.
(picture from Bret Victor's A Brief Rant on The Future of Interaction Design)
You need a system with a good "part that fits the problem" but also a good "part that fits the human" (inspired by Bret Victor's A Brief Rant on The Future of Interaction Design). To this end, it must be informed not just by theory, but also by human psychology. That's why I mentioned all that weird stuff in the last paragraph. Math is good if the theories are solid and proved, but even better if the proofs are elgant and simple in a way that lends itself to use by humans for building more math or whatever else. So I have tried to draw inspiration from everyone and how they work, especially how they work on tasks that demand aestheticism, since right-brained activity is louder there (this 'left/right' distinction being more of notational convenience than an actual statement on physiology/geography of the mind).
Again, bringing us back to the aestheticism surrounding games. Aeshetic end-points require creative work, testing our purpose of providing computer support for the creative spirit in everyone--that's a good paper on the design of Smalltalk you should check out. It says, "If a system is to serve the creative spirit, it must be entirely comprehensible to a single individual." and I'd go far as saying that "it must be entirely created by a single individual" :) In all seriousness though, if it takes too long to make and too many people, it's probably too complicated. The system should be so good that it helps itself be built, while being built. Like how morphs in Self exploit the prototype inheritance, and how cgame's editor GUI is itself built using the entity-system model.
Making development tools is also nice in that you're not just 'building a service' that people want to not think about and use and forget (like a search engine that answers the question and gets out of your way), but something that they are engaged in conversation with and work with together, like Ableton Live is to the music-maker or Photoshop for the artist. If you're a lumberjack, it's your axe that you so love and wake up in the morning to grab and admire, not your kitchen tap you never thought twice about. It isn't quite as taken for granted. And if it is a development tool for developers, the 'end-user' can actually code and release libraries, even bugfixes for your own tool, allowing for community aspects like the one surrounding the Ogre forums.
This brings us to yet another point, which is education. Would you rather tell a kid, "Hey, I'm gonna teach you what a for loop is, we're gonna print 10 numbers!" or "Hey, I'm gonna teach you what a for loop is, we're gonna make 10 space invaders enemies appear on screen!" What's more, kids are less informed (more like 'limited by') socialization into a current status quo for what makes a good game or a good piece of art, and would make some really cool things that I wanna see. Also they're probably highly critical of long and complicated words.
Lastly, I've been doing games for a while and have an accumulation of ideas in my head regarding what makes them annoying, and every decision I make sort of gives me flashbacks of past issues and a gut feeling about whether it's gonna help that issue.
Oh and, did I mention that... Games are just fun anyways? You might already know this.
Yeah, I totally wanna make game development tools. Or at least, 'interactive experience' development tools.
(Real-ish talk) Prototype-based programming
This is "a principle of abstraction that supports the above." The idea is: make abstractions concrete enough that they can be save/loaded and live edited.
See how that makes the principle 'support the above'? In the spirit of concreteness, what I mean is: things that we think of as 'classes' and 'types' (which are abstractions) should be actual tangible entities, that you can edit and play around with, the very same way you would play with 'instances' of those classes and types (their 'concretizations'). Tangible like for a sculptor with hands-on control of their art piece.
If we do this to the extent that an abstraction of an instance is literally the same 'kind of thing' as an instance (they are both now called 'entities'), then we should get this for free. They are made of the same stuff. The abstraction is also now clay in the sculptor's hands. You can paint the trait of 'dogness' with the same brush that you paint this dog here, but also that one there.
Enter prototype-based programming. This is what pgame is about.
(stay tuned for another blog post with a more in-depth idea description)
(bonus: Gilad Bracha goes far as to apply the abstract-to-concrete approach to 'functions' vs. 'running instances of functions')