Sunday, January 23, 2011

a humble bundle of shared words

me: hello? :D This is Tony Puccinelli, a CS student at UC Berkeley I just got done with finals and am looking forward to playing some "Revenge of the Titans", that game's got me hooked. anyone there? 
dev: hey tony! 
me: hey! so how are you related to the bundle? 
dev: i co-developed osmos 
me: oh nice! I've been playing that on my iPhone :D 
dev : nice! 
me: that game is so very relaxing but so very strategic at the same time. I like how every action you take jettisons part of yourself, nifty mechanic :D Actually, it reminds me a bit of "Orbient" on WiiWare. so how did you get into game development? I've been trying to learn Flash myself, and potentially have an interview with Telltale come March or April 
dev: we played that at some point, and yes, very similar aesthetic 
me: and similar in the sense of being moody and abstract and basing gameplay around one simple mechanic that just works really well; Thanks for the great game! 
dev: we just worked on osmos as a side project, that's how i got into game dev. i'm actually a comp-sci professor in my "real life" 
me: oh wow, so that was your first step into the industry? nice! 
dev: yup. worked out pretty nice :) 
me: What's your area of interest? in Comp-Sci, I mean, and at what school? sorry for grilling you with questions :P 
dev: computer graphics and geometric modeling, but these days with a huge emphasis on human perception and game design 
me: ah, nice, I lamentably have yet to take a graphics class, but have one scheduled for next semester; that said, I'm trying to make a Flash game over Winter break. I don't much like Flash, but feel as a complete unknown a Flash game will be easier to distribute and get feedback on. probably the most interesting course I've taken thus far has been Artificial Intelligence 
dev: you should try flixel and/or flashpunk. it's a really huge topic 
me: AI or graphics? well both are, definitely :-) 
dev: oh yes, both. graphics is crazy 
me: It was astonishing seeing all that's been done in AI and how it works (at a very high, rough level), but also very intriguing to get a glimpse at the more cutting-edge stuff, like Natural Language Processing, cars that drive themselves, the professor's starcraft AI :P graphics IS crazy 
dev: yeah, that genetic algo stuff is insane 
me: I'm pretty ignorant to the world of graphics, so very excited to dive into it next semester 
dev: super wide field. could use a bit more inspiration though :) 
dev: i'm much more interested in abstractions than trying to render the real world in all of its detail 
me: haha, yes, the remarkable, amazing power of computing is often wasted on simulating the minutiae of what we can already experience without computers :P well, not exactly wasted... :P 
dev: well, maybe a bit wasted :) i'd rather play real chess than holodeck chess :) anyway... i gotta run! great chatting with you! 
me: ok, very nice talking to you, and keep up the good work! 
dev: we'll definitely try hard! cheers! 
me: cheers!

Tuesday, December 7, 2010

Why It's Fun: World of Goo

The age of digitally-distributed media is upon us (I mean just look at this life-changing announcement!) and in the world of videogames this has most definitely been a good thing.

"Why?" you ask, sweat beading on your forehead in clamorous anticipation...

Because, sirs and madams, it has given startup indie game developers the means to distribute (and thus, the motive to create) games with fresh ideas that stand as beacons of hope in a monotonous minefield of first-person-shooters that have you trudging through monotonous minefields.

Case in point: World of Goo

World of Goo is a very strange game that has you building squishy, truss-like structures out of eager and eccentric goo-balls to reach up and up and up...

The game is fun because it taps into that child-like sense of discovery you first satiated in a sandbox during recess, learning through trial-and-error that the world has rules and that you can exploit them to create freakin' castles (and in my case, tunnels and moats to accompany said castles).

In other words, the game is fun because physics are phun (as is, surprisingly, Engineering), and the game's foundation is a cartoony approximation of physics on a 2d-plane that would make Newton proud and quite possibly queasy. The game understands that a sense of true interaction is a videogame's greatest asset; your in-game cursor leaves an ink-blot trail as you whip it around, frantically grabbing goo-balls who stop and stare at you with a satisfying "pop" as you mouse over them and who scream in zany mixtures of terror and glee when you throw them or, more constructively, incorporate them into a structure you're building. The constant feedback gives the player a sense that they're really an integrated part of this quirky, sarcasm-laced world with direct influence on its viscous inhabitants. Couple this with consistently inventive and imaginative level design that requires an ever-increasing intuitive understanding of the physics (each new level builds on the skills learned in the previous ones without ever repeating quite the same scenario) and a sometimes esoteric but always amusingly satirical sense of humor (with plenty of jabs at corporate America) and you've got a game that blows most big-budget productions out of the water (did I mention it was made by two guys whose office is whatever coffee shop they decide to go to on a given day?).

If the gameplay sounds very vague and confusing, it's because trying to describe in words such an original concept is akin to listing off a series of notes to convince someone that a melody is compelling. You really need to play a bit of the game to get a feel for it, and you can!

You can purchase the game from a host of places (including WiiWare and soon, the iPad) but if you buy direct from the dev's site this week only, they're donating 100% of the sales to some good charities.

Arbitrary Rating: 348 goo-balls

Monday, December 6, 2010

A new era for Pearls on a String

Following in the footsteps of some friends, I have decided to sporadically (which means there may be only one entry) review videogames on this blog that has been serving no purpose for the past few months in a series I will call "Why it's Fun".

These entries will, apart from the rest of this sentence, not be concerned with the ongoing "can videogames be art?" debate, which has wasted everybody's time in the wake of some old guy's rants that, while quite intelligent, aren't at all fair in an apples vs. oranges type of way (a tip: you can't judge an inherently interactive medium by watching YouTube videos about it; you aren't experiencing it as intended!); Rather, I'll treat these games as meticulously constructed experiences and leave what to call those experiences to you, dear lone reader of this blog!

But enough abstract pretentious blithering and onto specific pretentious blithering...


Tuesday, November 9, 2010

English is a Minor thing

I have become a medium through which words travel,
not a locus of their temporal deconstruction/assemblage-

a reader:

a plane upon which words flow and diverge and bead and flow again
from (and back to) the infinite and infinitely elusive edges

Sunday, August 1, 2010

Belated Blog

Hey all!

It's been a while since I last blogged (whoops!).

But in the time since my last post, quite a bit has happened.

First off, I got the DS port working with loadable modules after reintegrating the thumb-interworking code into the DS port. It was quite simple, really, as the thumb relocations used were PC-relative (and thus needed little to no manual work). I tested a good number of the engines after getting this work done, including the SCUMM, SKY, LURE, QUEEN, and AGI engines. They all seemed to work fine (though I only played through about 10 minutes of each game and I've heard some, like Sam and Max, use more memory later on). The one exception in terms of successful testing is the CRUISE engine. That plugin had a single relocation type (R_ARM_TARGET1) that none of the other engines have. This type is supposed to be treated either the same as R_ARM_ABS32 or R_ARM_REL32 (how it should be treated can differ, even in the same file). Since I saw no easy way to determine how it should be treated during runtime, I added "--target1-abs" linker flags to the ds makefile (the flags specify that R_ARM_TARGET1 should be treated as R_ARM_ABS32 in all cases) and coded for the R_ARM_TARGET1 relocation accordingly, but to no avail ("Cruise for a Corpse" still crashes on bootup, showing only the Cruise cursor). As of now I can't see the console (on the top screen of the ds) at the point of the crash, so debugging is difficult, but I'll continue to work on this.

Another problem with the DS build is that (as mentioned before) I had to remove the "--gc-sections" linker flags since things were being garbage-collected in the plugins and main executable that referred to each other. This unfortunately resulted in a lot of bloat in the main executable. For some engines, this bloat is around 300kb, which is too much to be ignored. There's been some discussion among the mentors concerning different ways to decrease this bloat, including building static builds with garbage collection and dumping the symbols then telling the linker to included only those symbols in the dynamic builds. In any case, this is something that will need to be worked on before the DS dynamic plugins work is reintegrated into the trunk.

Apart from the DS work, I did some work abstracting a more generic ELF-loader last week. It's a little rough at the moment, but works for both the PS2 and DS ports, so at least I didn't break anything :-). I put the methods dealing with relocations into their own files based on processor type (like arm-relocs.cpp and mips-relocs.cpp) and also split the shorts-segment-manager (made to effectively use the gp-relative section of MIPS processors) into its own file. There's still a bit of work to be done for abstraction, including making subclasses of DLObject (like PS2DLObject, which could be a subclass of MIPSDLObject, etc.) and having the different plugin-providers use these different subclasses (right now, I just used "ifdefs" with different ports).

I've also worked on a bit of the plugin design change work. It took me a while of looking through the base code to understand how to best begin implementing the plugin design changes, but I added some new functions to the PluginManager class (a "loadFirstPlugin" and "loadNextPlugin") as well as changing main.cpp and some functions in plugins.cpp to use these functions in a loop when "NEW_PLUGIN_DESIGN_FIRST_REFINEMENT" is enabled. I tested on a Windows build with dynamic plugins enabled and was able to successfully launch games with only one plugin ever loaded at a time!

So the plan for this week is to continue plugin design change, abstraction, Cruise for a Corpse, and DS memory problem work,


Tuesday, July 20, 2010

Good News for the DS port

Last week, I restructured the DS loader to use a SeekableReadStream for file reading. Once that was in place and working, I restructured the PS2 loader to use a SeekableReadStream as well and tested it (this needed to be done anyway and it helped me ensure there was nothing inherently wrong with the way I was using SeekableReadStream in the DS loader).

I then had problems reading the symbol table in successfully. After some wasted time :P, I realized it was just a silly mistake. I had neglected to initialize _symtab_sect to anything in dsloader.h and the value of uninitialized ints is undefined in C++. Thus, the loader was detecting, from the value that _symtab_sect had, that the symbol table was already read in when it wasn't.

At this point the loader was getting to the point where I had to deal with the relocations. I used consolePrintfs to make sure that the relocation types the loader was detecting were the same as the ones detected by arm-eabi-objdump (they were). I then began coding for these relocations. After a day of work on the relocations with no success as far as getting games to run with dynamic plugins enabled on the DS, I decided to disable the thumb-interworking on the ds temporarily so I could work on getting the DS with plugins in a runnable state without having to deal with the complication of thumb instructions/relocations.

I worked further on the relocations yesterday; I started dumping the instructions to be relocated and immediately noticed a MAJOR problem. Every instruction was 0x00000000! The addresses of the instructions seemed reasonable, though, so I suspected it had something to do with how the plugins were being built and not how I was retrieving target addresses. I dumped Mapfiles with "-Map" during plugin linking and discovered that whole input sections were being discarded, among other problems. After switching out the linker script for a modified version of the default "arm-eabi-ld" linker script, these problems seemed to be fixed, perhaps because the modified linker script I was using (based on the script used by the main executable) used the MEMORY command to map out different blocks of memory but I was trying to force the start address of the ".text" section to be 0. I am not sure whether switching out this linker script will cause problems.

I then did a fair bit of reading on the ARM instruction set and continued tweaking/testing the relocation code. Things still weren't working like they should have. Yotam suggested comparing completely unrelocated code and semi-relocated code to see what ld was already doing for me, and through a few dumps, I realized I was trying to do A LOT that ld already did redundantly and thus messing up things that were already fixed! After removing this redundant code, I got Beneath a Steel Sky to run successfully with Dynamic Plugins enabled on the DS!

My next order of business, then, is to test the rest of the engines (some of which have relocation types I still haven't dealt with). Then, I'll reintegrate the thumb-interworking and deal with any major complications that brings (if any :D).


Also, I plan to update my wiki schedule shortly:

Monday, July 12, 2010

a size-able problem with plugins

While working on changing how the loader opens and reads plugin files on the DS this weekend, I noticed that the ".plg" files produced in my builds were significantly smaller than expected (as in under a hundred kilobytes).

So I looked through verbose build output to investigate what the problem could be. The plugin linking output included all the necessary object files, so I knew the problem wasn't there and decided to look closer at the plugin flags.

Last week when I added the PLUGIN_LDFLAGS into the ds/arm9/makefile, I copied over the regular LD_FLAGS to make sure all the special DS optimizations that occur when linking the main executable would be used for the plugin files as well (stuff like "-mthumb-interwork"). One of these flags was "--gc-sections" which I believe is meant to garbage collect sections full of unused functions and/or data. Since both the main executable and the plugin files were using this flag (but plugins aren't truly linked in to the main executable until run-time), functions and data in the main executable and the plugins that point to each other and nowhere else were mistakenly garbage-collected. After removing the "--gc-sections" flag from LDFLAGS and PLUGIN_LDFLAGS, plugins are a much more reasonable size. Unfortunately, this means the main executable is a bit more bloated than before, which runs counter to the goal of using as little memory as possible on the RAM-starved DS...

But for now, I'll be moving on to reworking the loader to use "Common::SeekableReadStream" to read plugin files.