Procedural City, Part 14: Feedback and Assessment

By Shamus Posted Thursday May 7, 2009

Filed under: Programming, Projects 63 comments

Short version:

Thanks for all the feedback on Pixel City. Stating your version of windows and graphics chipset along with problem reports is invaluable. The current release version has a rather embarrassing memory leak in it, so prolonged use will make the system thrash for a while when you exit it. For those of you compiling along at home, this is already fixed in the codebase and you should integrate revisions #11 and #12, regardless of what else you’re doing with your own forked version.

For this reason, I’ll be issuing at least one more build of Pixel City that fixes this problem. I’d like to kill a few other issues in that same release if I can gather the data needed to do so.

Long version:

I want to start with this comment from Brandon:

I'm using an ancient machine (think 2003 or 2004). Barely 1GB of DDR RAM across three sticks, I don't even want to know what my processor is like, and the best thing in here is a 512mb AGP graphics card. But the screensaver runs relatively smoothly, provided I have absolutely nothing else running on my computer. With about four other applications open I average 15-20fps and managed to get up to 50fps when the camera swooped low and followed a street

This is very much what I expected: Just barely useful on a five year old machine. That fits with the my impressions on what we should be seeing, which is why I was very taken aback by reports from people with two or three year old machines that said the thing took ten minutes to start and ran at 2 frames per second. This was very alarming and had me worried that I’d somehow grossly misjudged what I was asking of the graphics hardware and the CPU. Brandon’s comment hints that I was probably right in the first place, and that these extreme slowdowns are coming from somewhere else.

Also interesting are reports from people claiming that it doesn’t work with multi-monitor setups, and other comments saying that it does.

The screensaver functionality was added late in the project, and was thrown together more or less at the last minute. I was slightly dubious about taking a system I’d built carefully (but not adequately tested) and setting it atop a system I’d built in great haste and hadn’t tested at all.

For the record, the program makes no special effort to support or not support multi-monitor setups. How Windows screensavers work is that your program is invoked and instead of manually creating a window yourself like you do in most programs, you are simply given a pre-existing window to use. This can be a bit strange when you’ve got a 1920×1200 monitor in front of you and (say) a 1024×768 monitor to one side and Windows is creating a single frame to encompass them both. One obvious problem is that windows must be rectangular. Assuming the small window occupies the same vertical space as the larger one (which is by no means certain) then your program is going to have a 2944×1200 region to fill. Even worse, within that render-hungry expanse is going to be a 1024×432 rectangle that’s being rendered and then discarded.

(EDIT: And just to be clear, the program doesn’t really have any idea that it IS on a multi-monitor setup. It’s just handed a window. I’m sure it’s POSSIBLE to query the setup and the monitor sizes and their geometic relationship, but I’m sure that would be a lot of work, and I’m not even sure what benefit it would be. The program still has just one window and one render context.)

How that window behaves and what monitors is spans is very much open to how multi-monitor support has been implemented. I know some graphics cards have their own multi-monitor setups that exist outside of the same functionality as provided by windows. Couple this with the fact that different versions of windows probably have different ideas about how window regions are stitched together and you have a recipe for something that will take a lot of time and experimentation with different monitor setups to understand. Keep in mind that I was never really that interested in wrangling with the Windows screensaver functionality. My real goal was the procedural city stuff, and the rest of the project was just scaffolding to support that idea.

The extreme slowdowns are a little more perplexing, and right now my instinct is to again blame the unknown behavior of the Windows screensaver functionality.

The directions I’d read online indicated that Windows would provide your program with a pre-existing window, and would then call WM_PAINT as fast as possible. I was a bit surprised at this, as this is a break from the behavior we see elsewhere in the operating system. Normally a window only gets a WM_PAINT when its contents need to be redrawn. If you move a window around the screen, resize it, or bring it out from behind other windows, it gets a WM_PAINT message letting it know that it needs to redraw. But here we have a situation where WM_PAINT is supposedly being called indiscriminately, and at an unknown (or undocumented) interval.

I’m strongly suspecting that WM_PAINT isn’t getting called very often on some systems. In screensaver mode, everything is bound to that one WM_PAINT message, which is putting a lot of trust in a feature that I don’t know much about and didn’t make sense to me in the first place. If Windows only calls WM_PAINT twice a second, then the program will take ~512 seconds to build the world and will run at two frames a second no matter what hardware you have. This seems to meet with observations.

One solution is to set up a WM_TIMER and see if that solves the problem. This would let me direct windows to call me every (say) 17ms or so, which would give me the desired 60fps framerate.

 


 

Another XKCD Ripoff

By Shamus Posted Wednesday May 6, 2009

Filed under: Pictures 32 comments

I don’t know why, but here is another one. With apologies to Randall Munroe.

Fine! No more rhymes if you feel so strongly about it.

 


 

Webby Awards

By Shamus Posted Wednesday May 6, 2009

Filed under: Video Games 26 comments

Congrats to the crew at The Escapist for winning another Webby award. Sadly, they lost the “people’s choice” award. They were ahead until the final day, when an abrupt surge of votes put Gamespot out in front. Although, as Spinwiz put it:

What about the People’s Voice Award you ask? Well, unfortunately we were edged out at the last minute, but that is okay. We showed a CBS-owned site that is 7 times our size just who The Escapist is, taking the fight to the end. So, please look at it this way: 300. If the award were given out on the basis of the percentage of site size to actual votes, we would have won by a landslide.

My warm relationship with The Escapist aside, I really hated to see GameSpot win. Gamespot personifies everything I hate (and have ranted about over the last four years) about gaming media. Their hype-focused tone. Their bland reviews with the soulless numeric score punchline. Their faceless writers. Their agonizingly ad-soaked bandwidth-choking wallpaper of visual spam they call a front page. Their apathy towards the indie scene. Their spamming. And let’s not forget what they did to Jeff Gerstman. In short, their site is ugly, shallow, and blurs the line between journalism and prostitution.

On the other hand, Destructoid is a worthy site. I hadn’t taken an interest in the place before I saw them as a rival in the Webby awards. (I think their tagline does them a disservice. “The hardcore gamer’s community” does not sound intriguing to me.) The site is fast, fun, and (as I mentioned in last week’s column) personality-driven. The fact that they got less votes than Gamespot is a crime. This should have been Destructiod vs. The Escapist, with Gamespot ranking just below this one in terms of community and entertainment value.

Sorry to get all bitter, but it’s disappointing to see that Gamespot is what people really want. I think the site has a negative impact on gaming as a hobby, and seeing it defeat Destructiod and The Escapist is like seeing people demand yet another reality show instead of a second season of Firefly.

On the upside, The Escapist won, and my work was a small part of that. That’s pretty gratifying.

Congratulations again to the crew at The Escapist.

 


 

Procedural City, Part 13: “Release” of Program and Source

By Shamus Posted Tuesday May 5, 2009

Filed under: Programming, Projects 191 comments

Screensaver


Link (YouTube)
I hesitate to call this a “release”. The program has been tested on exactly one computer, which can’t even be called a “test” with a straight face. Not only is this not a release version, it’s not even beta-worthy. Even internal alphas have undergone more scrutiny than this program. It is only my boundless hubris that allows me to call this “version 1.0”.

But I don’t have any machines suitable for testing right now, and I don’t have time to run some sort of open beta. Besides, any such effort would quickly fill up with people who were just there for the software and not really into the whole “test unreliable software and then report in detail all the ways in which it failed to work”.

So I’ll preface this release with a stronger version of the usual disclaimers: No warranty is implied, it might not work, use at your own risk.

Sorry to the Mac users. I do not omit you out of malice, but I’ve never developed for Macs before and have no means of doing so.

Download PixelCity v1.0

Take the PixelCity.scr file out of that archive and put it into your /Windows directory and you should be ready to go. There is no configuration dialog, so when you hit the “settings” button in ScreenSaver configuration, nothing will happen. Just hit F1 while the program is running to get a list of things you can do. Be sure to press ‘E’, as it will show off some full-screen effects I haven’t mentioned or showcased before. (I wanted to have some surprises! Although perhaps seeing the message “This program as performed an illegal operation and needs to close” will sate your desire for surprise.)

Please do consider spreading the word on this project on your blogs or wherever you tell people about cool stuff. Reluctant DM was nice enough to put it up on Digg, but Digg has yet to respond to anything I’ve done. Projects, comics, articles. I’ve gotten links from some internet hotspots, but I’ve never earned more than an indifferent shrug from Digg. It’s a very FARK-esque audience and I doubt I’ll get any digs until I write my magnum opus: Procedural Man Getting Hit in Balls with Baseball. (It works on so many levels!)

Source

I’ve put the project on Google Code, although I’m not sure if I will continue with the project or not. I’d love to keep working on it, but further changes will most likely make for dry reading, and that means the project would no longer be feeding this website. We’ll see.

I’m using MS Dev Studio 6, which turns eleven years old this year. Sorry to those of you using development environments forged sometime during this millennium. This is something I cannot change. Although to be fair, migrating from my platform to your is likely much easier than going the other way.

Development

In Win.h there is a #define that lets you disable screensaver mode, which is crucial for development. Setting SCREENSAVER to 0 will change the behavior of different parts of the program and give you access to the primitive and unintuitive development camera.

If you want to test it in screensaver mode, set SCREENSAVER to 1 and invoke the program with the /s command-line option.

Porting

The program is very much tied to Windows at this point. I tried to quarantine all of the Windows-specific code into its own ghetto module (Win.cpp) but that didn’t really work. The stuff for generating a render contex and loading fonts in Render.cpp is also windows-specific, and of course you must #include windows.h everywhere you use Gl.h, which is just about everywhere. And finally, checking the millisecond timer means calling the Windows-specific GetTickCount (). So those items will probably form your to-to list if you’re looking to port.

Optimizations

There is a lot of work that could be done to speed this thing up. Many promising ideas were suggested in the comments during the three optimization posts.

Switching to vertex buffers would likely give a huge boost. (See the comments at the top of Mesh.cpp.) A lot of improvements could be made to the visibility table and how cell visibility is determined. And I suspect there’s a better way to fill the bloom buffer than the one I’m using now.

I didn’t pursue these because there’s just no point in trying to optimize any further on this machine. To be done right, the changes need to be done on an older machine. Profiling can help, but only in cases where old and new hardware encounter the same bottlenecks. The thing runs at 200fps+ on my machine, and it’s entirely possible that I could ratchet that up to 300fps in such a way that provides almost no benefit to the poor guy running the thing on an old laptop. Furthermore, at this speed it’s pretty hard to detect improvements amid the noise, so it’s hard to get a feel for how effective changes are. (Again, profiling doesn’t tell you about those every-ten-frame lurches that are imperceptible at 200fps and nauseating at 20fps. There is simply no substitute for testing on the right hardware, which is why the loss of my old computer was such a terrible blow. I’m currently watching family members to see if any of them are going to upgrade soon. Ideally, I hope to inherit a ~2004 machine.)

Still, I’d start with vertex buffers.

Derivative Work & Collaborations

I am gratified to see that so many people want the source and are eager to do new and cool things with it. I’m not sure how we should go about this. Google Code isn’t up to tracking a dozen forks of the project, and I don’t have time to administrate that sort of activity anyway. Ideally we want someplace where people can swap code, knowledge, and screenshots. Some people will no doubt struggle getting it to compile on their different (from mine) development environment, and a little help from others can go a long way towards saving everyone time & headaches.

This is ideally the job of a forum, but I’m not in a position to provide one of those right now. It would be perfect if such a thing was available along with Google Code, alas.

I’m open to suggestions.

UPDATE: The codebase is now available on GitHub, which has the source file / social functionality we’re looking for:

http://github.com/skeeto/pixelcity/tree/master

Future Work

While I have many features I’d like to add, I don’t have any immediate plans to do so. Right now I’m going to wait and see if there are any egregious problems with the screensaver.

But if pressed, I suppose I’d like to add the following someday:

  1. Port the thing to wxWidgets, which might give me the cross-platform access I’ve always wanted. (Win, Linux, Mac.)
  2. Implement vertex buffers.
  3. Fiddle around with the city-generation parameters. I don’t think I’m getting as much variety out of the existing code as I could. More mid-size (25 story) buildings with a large footprint might do a lot to break up the “bar graph” effect I have going now.
  4. And of course, the street-level detail is a timehole which is happy to consume any effort I’m willing to put into it.

Thanks for reading. It’s been fun.

 


 

Stolen Pixels #86: Left 4 Dumb: Part 9

By Shamus Posted Tuesday May 5, 2009

Filed under: Column 13 comments

Herein is a treatise on the ribald expressions of individual accomplishment against those which are ostensibly one’s own peers within a fiercely competitive environment.

(AKA teabagging.)

 


 

Procedural City, Part 12: Finishing Touches

By Shamus Posted Monday May 4, 2009

Filed under: Programming, Projects 49 comments

You’ve most likely witnessed the thing in action already, but I thought I’d go over the final steps.

Building Logos

pixelcity_logos.jpg
Building logos are fairly simple, although they make the project a little less portable. The program generates 16 random names and draws them into a single texture. Individual buildings then grab one of the sections of the texture to use as its logo, which is then colored semi-randomly. Each name is drawn in a random Windows-specific font. The selection and use of fonts will probably be one of those things which is annoying to port, assuming anyone does so.

Prefix Business Suffix
i 
Green 
Mega
Super
Omni
e
Hyper
Global 
Vital 
Next 
Pacific 
Metro
Unity 
G-
Trans
Infinity  
Superior 
Monolith 
Best 
Atlantic 
First 
Union 
National 
Biotic
Info
Data
Solar
Aerospace
Motors
Nano
Online
Circuits
Energy
Med
Robotic
Exports
Security
Systems
Financial
Industrial
Media
Materials
Foods
Networks
Shipping
Tools
Medical
Publishing
Enterprises
Audio
Health
Bank
Imports
Apparel
Petroleum 
Studios
Corp
 Inc.
Co
World
.Com
 USA
 Ltd.
Net
 Tech
 Labs
 Mfg.
 UK
 Unlimited
 One

The names themselves are generated by combining elements from the three lists to the right. The first column is for descriptive self-aggrandizing that companies like to give themselves. The second is generally the name of a good or service that a boring conventional company might use in its own name. And the third column is for for the dry descriptive that generally follow the name of a business. Pixel City generates business names by taking a random entry from the center column and pairing it with either a prefix or a suffix, but never both. So you might end up with “Vital Imports” or “Imports Tech”, but never “Vital Imports Tech”. Using all three works in some cases, but looks ungainly in others. It also gets hard to make sure it all fits on the texture. A bad roll could bring the three longest entries together and make something verbose like, “Monolith Enterprises Unlimited”. Which doesn’t sound nice and won’t fit on the texture. (The system I’m using to draw characters is pretty primitive and doesn’t have the ability to predict how long something is going to be before it gets drawn.)

Obviously not all names make perfect sense. (iPetroleum? Really? Are you drilling for oil on the internet?) But most names are plausible enough and have a respectable level of variety. It can make 1,221 unique names right now, and every once in a while I think of another entry to make it even more diverse. Note that some prefixes have spaces after them and some don’t, so you’ll end up with “iMedia” in one case but “Pacific Media” in another.

Streetlights

I’m still not happy with how the street-level lighting came out. If this was a Game Developer Magazine Postmortem, then we’d be explaining how this feature put us a year over budget. I spent more than a few hours writing different systems, tweaking them for a few more hours, and then deleting them to try something else. The problem here is that my initial idea of simple dots for lights didn’t look anywhere nearly as good as I’d hoped, and I lost a lot of time searching for another solution. In the end I came back to my original idea and just decided to live with it. Many people looked at the screenshots and suggested the lights be bigger / smaller / higher / lower/ closer together / further apart, but these problems are just emergent results of the underlying problem that light simply doesn’t behave the way the program depicts, and the break in fidelity attracts the eye and draws attention to the weakest part of the scene. Changing the lights by making them (say) higher would simply change the problem being reported by your eyes. “Oh, now it’s too small… Now it looks too bright… Now they look too far apart… Now they look too far off the ground… etc.

It will be interesting to see what other solutions people come up with once the source is released. Perhaps someone will find the silver bullet solution that eluded me.

Roof lights and radio towers

Image lightened in Paint Shop in order to make the towers more visible against the sky.
Image lightened in Paint Shop in order to make the towers more visible against the sky.
I decided early on that making elaborate illuminated stonework caps for buildings was out of the question, but feedback was telling me the dark rooftops just weren’t cutting it. I eventually settled on adding some non-illuminating light fixtures to the caps of tall buildings, which added variety without complexity and without needing fancy stonework.

The radio towers are a simple 4-triangle spike with a lattice texture applied. A blinky light is added to the tip. I have a blinkentower on almost every tall building, and I still get complaints from people to the effect of “you should have some towers on the tops of those buildings”. I think they’re just too hard to make out in the low-res screenshots and YouTube video. Spotting a few black lines against an almost-black background amidst a sea of compression artifacts is no easy task, but I think that when viewed full-screen they’ll look good enough.

Screensaver Behavior

When invoked, the program generates a city (unlike in the demo video, this is done behind a loading screen) and then the camera flies around it for a few minutes. There are a few keys that change the program behavior. There is a key to toggle wireframe, another to cycle through the special effects, from bloom to the “glass city” effect shown earlier. F1 shows the full list of keys. Pressing any other key just exits the program, as screensavers do. After a couple of minutes the scene fades out and another city is generated. Rinse, repeat.

Tomorrow: The source and the Windows Screensaver will be released.

 


 

Left 4 Dessert

By Shamus Posted Sunday May 3, 2009

Filed under: Links 8 comments

The internet is a strange place where you can learn about things you need which you didn’t know you needed. For example, Left 4 Dead cookies.