4 ms·
I worked on a port of Micropolis to the Sega Dreamcast, but never finished it. https://www.youtube.com/watch?v=MlFu-y1LDbs https://www.youtube.com/watch?v=MlFu
by TapamN 2y ago
I worked on a port of Micropolis to the Sega Dreamcast, but never finished it.
https://www.youtube.com/watch?v=MlFu-y1LDbs https://www.youtube.com/watch?v=MlFu-y1LDbs
One thing I really disliked about the SNES port of SimCity Classic was how slow the interface was. Having to access the menu for everything was a pain. For my port, the cursor would move faster, and snap instantly to the next tile if it was tapped. The analog stick could be used for fast cross map movement. The menuing was replaced by mapping every command to a button combination, with different palettes of commands available depending on what shoulder buttons were pressed.
If you weren't holding a shoulder button, the ABXY buttons were set up for A (primary action button) for roads, X (secondary action) for rail, Y (the green button) for parks, and B (cancel button) for bulldozer. Holding L was reserved for system commands, you could zoom in or out with A or Y, and adjust the speed with X and B. Holding R completely would allow building zones, color coded to the controller's buttons, with the red (A) button to build residential, blue (B) for commercial, and yellow (X) for industrial. There were two more palettes, accessed by either pressing L+R, or half pressing the R button, for infrequently built things like power plants and airports. It might sound complicated from the description, but I think it would be pretty easy to get used to if you actually tried it a bit.
I did a bit more work after I made the video, like adding map overlays (pollution, traffic, etc) and a display of what the current face button palette is, to help learn the combinations.
I was also adding split screen, for multiplayer. I was planning for you to be able either build a city together with someone else, or do competitive city building, like race to clear a scenario, or get the highest population or funds in a certain amount of time. I think I got the split screen two different cameras on the same city working, but no controls for anyone besides player 1.
I spent some time optimizing the simulation, because I wanted absolute solid 60 FPS. There would be occasional 1 or 2 frame stutters on large cities went certain phases of the simulation ran. The worst was when it calculated power.
The power grid connectivity is calculated in a bizarre way. Instead of a regular, scanline based flood fill, it basically has a Logo turtle walk the power grid. It uses the exact same class that the monster uses for movement, tracking the facing of the turtle, with functions to turn, take one step forward, etc. The version of GCC I was using was not automatically inlining the movement functions (they were in .CPP files, and no LTO), so it added a ton of overhead to an already slow algorithm. I moved the functions into the header so they would be inlined, which helped a lot, but was still planning to replace the whole thing with a real flood fill.
Even after inlining the walker, there were still single frame stutters. A lot of the map data for things like pollution and land value have filters applied to them, and the filter has a slow implementation. It does X and Y bounds checking on every tap of the filter, even in the middle when it can't go out of bounds. A better filter implementation would have helped.
The C++ simulation seemed to have some kind of bug, which would cause periodic mass abandonment, that I never figured out. I never noticed the Java version having the same problem.
- DonHopkins 2y agoAmazing! Decades ago, Will Wright suggested to me a nice optimization for cellular automata and convolution filters that lets you eliminate the bounds checks in the inner loop, which I implemented in my CAM6 cellular automata machine simulator: Eliminate the edge conditions (and conditionals in the inner loop) by making a "gutter" of one extra pixel (or however many pixels your neighborhood extents out) around all the edges of the bitmap (i.e. increase the width and height by 2, then inset x and y by 1), then before processing each frame, copy the appropriate edges into the corresponding gutters (wrapping or clamping), then iterate over the pixels just inside the gutters, so you don't have to perform any bounds checks. https://github.com/SimHacker/CAM6/blob/master/javascript/CAM6.js#L263C1-L281C1 https://github.com/SimHacker/CAM6/blob/master/javascript/CAM... // Optimization Techniques // // Extra copying is eliminated by swapping between two cell buffers, // one for the past and the other for the future. After applying the // rule, the past cell buffer becomes the future, and the future // becomes the past. It's necessary to have two buffers, because // you can't apply cellular automata in-place in one buffer, since // you would stomp on your past neighbors whose future you just // computed, since the neighbors above and to the right would be // from the future instead of the past. // // Edge conditions eliminated from inner loop by making cell buffers // two cells wider and taller, and wrapping edges around to the // extra edge cells before applying rule, so the inner loop does not // have to check for edge conditions to wrap the cells, and other // edge treatments can be applied besides wrapping, like clamping or // reflecting. // https://github.com/SimHacker/CAM6/blob/master/javascript/CAM6.js#L13795 https://github.com/SimHacker/CAM6/blob/master/javascript/CAM... // wrapCells wraps the cell edges. [...] You can either wrap the cells into the gutter from the opposite edge like a torus, which makes nice seamlessly tileable patterns, or in the case of something like SimCity pollution diffusion, you can just clamp the pixels into the gutter along the same edge. Shaders have a way of wrapping and clamping and mirroring automatically (wrapping modes): https://webglfundamentals.org/webgl/webgl-3d-textures-repeat-clamp.html https://webglfundamentals.org/webgl/webgl-3d-textures-repeat... But on old school consoles you have have to use software tricks like that instead of relying on the hardware. And of course if you're using power of two sized bitmaps you can just mask the coordinates, which is practically free. You could fix SimCity to use that trick, but it would make the code more complex, and it's probably not worth it on anything but really old hardware like the C64 or Sega Dreamcast.