We Got Dungeons - Dev Log 3
A look at structures and game objects for our tactical RPG on the Sega Genesis and Mega Drive.
A look at structures and game objects for our tactical RPG on the Sega Genesis and Mega Drive.
Last time we announced our new upcoming game for the Sega Genesis, We Got Dungeons.
This time we'll delve into the technical details of the game, so strap in for some tech talk!
First off let's talk about the levels.
We are planning on having several different tiers of levels, each of them comprised of several floors of increasing difficulty. The levels are broken down into separate discrete rooms that are filled with randomly generated encounters.
In order to maximize the number of different rooms that we have to work with, and make each room as interesting and varied as possible, we have an elegant yet simple system in place.
First, we create a room template that is a plain old matrix of numbers. Looks something like this:
Now that we have these templates we can easily generate a floor map by stitching multiple rooms together.
You can notice that in that example we have 6 as a decorative object that is 3 tiles wide. When the room is generated a random object will be picked and placed there.
This approach gives us the ability to quickly create lots of room templates and have them appear random but at the same time have enough control to give each and every single room that handcrafted feel that many procedurally generated levels lack.
But this is ROM memory, so how do we use this in the game. Well, we have a matrix of pointers to game objects (we will talk about those structures in a later post so stay tuned) that point to whatever is loaded in at that particular square. After that, we can finally draw those objects on the screen. Right?
Unfortunately, there is one last catch. The internal data structures are normal matrices that represent 32x32 pixel squares on the screen. But We Got Dungeons uses an isometric perspective. This means that we have to transform the Cartesian coordinates of a square grid matrix into isometric coordinates.
Due to the isometric perspective, the art is "squished" and the grid runs at an angle of 26.565°. That number is very specific for a reason, and this is where a little bit of maths comes in very handy.
A slope of a line is defined as the ratio between the change of the y coordinate and the change of the x coordinate or:
With a little bit of geometry we get the following:
Looking at this picture it is clear that the slope is:
Which in our case is tan(26.565). Google tells us that the tangent of 26.565 degrees is 0.49999888349. Which is close enough to 0.5 which in turn gives us a nice ratio of 2:1.
Now we can use this simple ratio to convert the square coordinates into isometric coordinates and draw the art at the proper coordinates on the screen.
Thus, we are able to generate good looking, unique dungeons for each and every playthrough of the game. Check out part 3 in our series to talk about the game objects and how they interact with each other!
We got a danger. We got to battle. We got tactics. We got a choice. We got a story. We Got Dungeons.
Imagine that Neil Gaiman wrote a novel about Buffy the Vampire Slayer investigating some weirdness in Earthbound. Now imagine that this novel was actually a tactical RPG with some rogue-like elements and a unique progression and customization system. Now imagine that this RPG came out for the Sega Genesis in the 90s.
Still with me? Good…
We Got Dungeons is a tactical RPG with:
In a 90s suburbia, not everything is as fly as it seems. Beneath the veneer of normalcy lies cynicism, doubt, and dissatisfaction with life. People want something, they just don't know what that is. But forces from the beyond think they have the answer, and things get weird when they begin to enter our world through the mundane. Weird like your neighbor’s basement going down ten floors. Weird like movie rental stores that are bigger on the inside than on the outside. Weird like your favorite VHS tape trying to choke you to death.
These forces are launching unannounced, unplanned, uninvited visits to our reality. It’s an unbidden invasion of suburbia, an unsought for contact from beyond the screen that separates us from them… and it all starts in your town…
So who is gonna step up to stop this invasion? Who can we depend on to turn the tide of this sinister threat? The military? Superheroes? 90s cartoon characters?
Actually, the world’s last hope is your mother.
Eschewing the traditional RPG/tactical RPG heroes of knights, wizards, and rogues, We Got Dungeons features ordinary people in a situation that is definitely buggin’. Luckily, the weirdness that is creeping in from the other side is amping up some of their everyday abilities. Let’s meet a couple of our unsung heroes:
The Troublemaker
She’s a high-school delinquent that cuts class, smokes, and runs afoul of the local neighborhood watch. Whether it’s flaunting the town’s “No Skateboarding” laws or tagging the convenience store with graffiti, you know the troublemaker is to blame.
Her skateboard and spraypaint come in handy as useful weapons, and she has a variety of skills (like bullying and shoplifting) that make her a versatile character.
Your Mother
Dear old mom. Everyone has one. Always there for you, she’ll love you forever, no matter what you do. But don’t let all those bedtime stories, embarrassing baby pictures, and boo-boo kisses fool you; when push comes to shove, mom is who you want on your side to fend off the forces from beyond.
Mom can make you feel better, easing all your troubles and woes with a hug. Or she can totally mess up your social life by grounding you. Either way, the weirdness invading our reality is sure to find out that there is no such thing as “just” a mother.
Want more dungeons? Keep reading our series of dev logs here. More classes, tons of weapons, armies of 90s enemies -- we are pushing the Sega Genesis to its limits for this one. Next time we’ll introduce some abilities that put the "Tactic" in "Tactical RPG", and a dungeon boss you may recognize from a famous basement…
Mega Cat Studios
OVERVIEW OF VDP CONCEPTS
VDP
"Video Display Processor"
Video controller chip that handles the Genesis' tile graphics, scroll planes, and sprites. Not actually a processor
VRAM
"Video RAM"
RAM used by the VDP
Holds tiles (8x8 px images)
Two main machine types
NTSC machines
"Sega Genesis", 60Hz machines, primarily found in the US
Resolutions
H40 mode - 320x224 px (40x28 tiles). More common resolution mode
H32 mode - 256x224 px (32x28 tiles). Less common resolution mode
Mega Cat games are NTSC releases, so use these resolutions!
PAL machines
"Sega Mega Drive", 50Hz machines, everywhere else
Resolution
H40 mode - 320x240 px (40x30 tiles). More common resolution mode
H 32 mode - 256x240 (32x30 tiles). Less common resolution mode
NTSC Model 2 Sega Genesis
PAL Model 2 Mega Drive
(European)
3 graphics planes
Displays tile graphics via tilemaps
Tiles for a sprite rendered in normal format (4x4 tiles)
1 sprite plane
Draws sprite tile graphics
Internally, sprites are rendered in reverse order; i.e., each column of tiles is rendered by rows
Sprites are positioned in a virtual 512x512 px space, with coordinate (128,128) being the top left corner of the TV display.
Genesis can display up to 80 hardware sprites on screen at once
Genesis can display ~20 sprites on the same scanline before sprite overflow issues occur and sprites are not displayed
For hardware sprites, sprite sizes are limited in size to (w x h) sizes, where w is width, and h is height, where each dimension is 1-4 tiles.
Sprites larger than hardware sprite sizes can be obtained by using multiple sprites
Like with planes, the tiles for sprites can have a low or high priority. Low priority sprites are displayed behind high priority tiles in other layers. (It's a little more complicated than this, but this is the basic concept in a nutshell)
Tiles for a sprite internally rendered in sprite format (transposed, 4x4 tiles)
Visualization of priority of plane layers
Source: Genesis Software Manual
VDP CRAM ("Color RAM")
4 palette lines, each with 16 color entries
Each color entry has a color depth of 4bpp (4 bits per pixel)
1st color entry is the transparent color for tile art
Palette lines can be rendered to use slightly lighter or darker colors by toggling highlight or shadow modes, respectively
BACKGROUNDS
There are 2 tilemap planes available for use on the Sega Genesis: a background plane ("Plane B") and a foreground plane ("Plane A"). Depending on the machine type (NTSC or PAL) and the video mode used (H40 or H32 mode), a full-screen tilemap will take up either a width of 32 or 40 tiles by a height of 28 or 30 tiles. Each tile consists of an 8x8 px image, with each pixel corresponding to a color entry index (0-15). The window plane is technically a subplane for Plane A; its graphics will not be scrolled with the rest of Plane A. The planes can be used in many different ways, such as fullscreen foreground and background layers, or for a technique many Sega Genesis games are famous for,parallax scrolling. By scrolling certain rows of tiles on the planes at different rates, an illusion of depth is created. Tiles in the different planar tilemaps can have a priority setting: either low or high. This setting will determine if sprites (which also can have a low or high priority setting) are displayed below or above the tile.
VSRAM (Video Scroll RAM)
Layers Plane A and Plane B can have scroll plane tilemaps of sizes (w x h), where w is width in tiles, and h is height in tiles, and where each dimension can only be of a size of 32, 64, or 128 tiles. These scroll planes are "scrolled into/out" of the active display resolution (size determined by machine types and H32/H40 mode). Scroll planes of sizes 128x64/64x128 & 128x128 are invalid due. By default, the sections of VRAM at default VRAM address 0xC000 and 0xE000 are displayed as "garbage tiles", but actually each pixel of those "garbage tiles" compactly encodes the VSRAM tilemap. The user should never write real tiles to these "garbage tiles" or weird graphical bugs/crashes, slow down, or garbage tiles will appear in the scroll planes. Planes can use 1 of 3 different, scroll modes: by scanline, by tile, or block (a section of 2x2 tile). Each plane can be scrolled horizontal, vertically, or both.
COLOR
Mastering the Genesis’ color restrictions is probably the best thing you can do to get the most out of your graphics! Tiles can only make use of 1 of 4 palette lines at a time. Each palette line has 16 color entries. The 1st color entry is reserved for the transparent color, which is recommended to be a solid purple of color (255,0,255) (RGB). You may want to allocate 1 or 2 palettes to stay consistent throughout the game, for a particular usage. For example, palette line #1 could be used for your player character, while palette line #2 could be used for UI elements. Enemies, backgrounds, and other changing elements through the game can make good use of different palettes.
To get the most out of the color in this piece, two palette lines were used; one for each tilemap plane layer. The first two images are each layer (Plane B and Plane A, respectively) shown separately, while the third image is the final fullscreen image using both planes combined. As each tile can only use the indexed colors from one palette line at a time, taking advantage of a dual-plane image setup like this allows many colors in tight spaces that only a single plane image wouldn’t allow enough colors for.
Two common color palette techniques are palette cycling and raster effects. By changing the color of particular entries in individual palette lines in-game every few frames, all of the tiles utilizing that particular palette line and color index setting will update to the new color. This is used for effects such as waterfalls, pulsating lights, etc.
Sample palette cycle effect for the flashing Beserk bars in Zombie Football LeagueRaster effects are changing all or some of the palette line's colors after a certain scanline. Performing this technique is beyond the scope of this document, but basically is swapping out all or part of entire CRAM's colors after the electron beam of the TV is past a certain horizontal scanline. This is useful for techniques such as applying a different palette for objects that are underwater and is used for underwater colors in Labyrinth Zone for Sonic the Hedgehog.
SPRITES
The base idle position sprite for Ashley from Coffee Crisis
Sprites for the Sega Genesis are defined as images with a size of (w x h), where w is the width in tiles, and h is the height in tiles, where each dimension can range from 1-4 tiles. Each sprite can use only one palette line at a time. Hardware sprites can have a max size of 4x4 tiles. The Sega Genesis can handle up to 80 sprites on screen, 20 sprites per scanline, though it’s worth staying under this limit to avoid slowdown. To overcome the hardware sprite limit, many games utilize multiple sprites together for one character/object to accommodate larger sizes. A classic pixel art principle is to keep your graphics at a resolution large enough to allow suitable detail and clarity, but small enough to easily animate. All Sega Genesis tile art should always be divisible by 8 pixels, to align with tile sizes! Sprites can be flipped horizontally ("hflip'd") and/or vertically ("vflip'd"), as well as have either a low or high priority flag set. This priority setting determines whether the sprite will be displayed above or below tiles in the other planes (which also have a low or high priority setting). Hardware sprites can also have a "link" value; each sprite must have its own, unique link value. Among other effects, sprites with lower link values are drawn above sprites with higher link values.
ANIMATION
A running armoured Minotaur football player, from Zombie Football League
In most games, the graphics will be animated, not just static sprites. By changing frames for sprites over time, the illusion of movement can be achieved and is used to portray walking, attacking, getting hit, etc. Different games deserve different styles of animation, and there are many specific animation tutorials worth checking out online. For the Sega Genesis specifically, be mindful about the number of sprites and tiles each animation takes up, and be sure to not go overboard with the number of sprites in each animation, especially if it will cause game slowdown. Sprite animation is often a battle between keeping a low individual frame and tile count and an appealing motion; this especially applies to animation on the Sega Genesis too. Focus on creating clear, readable keyframes so that the action in your animation is apparent, and take advantage of holding certain frames for different time durations.
A common animation technique used is commonly called "Dynamic Pattern Load Cues" (DPLC) among the Sonic the Hedgehog ROM hacking scene. This is the term coined for dynamically uploading the tiles for sprite frames into VRAM on-the-fly, rather than storing all of the tiles for all sprites frames into VRAM all at once. Many times, for detailed sprites (such as the player sprites), the number of tiles utilized for all of the sprite frames will take up too many VRAM tiles. By uploading only the tiles you need for the particular sprite frame being rendered, you conserve your limited VRAM memory to be used for other tile graphics. Unfortunately, the tiles used for DPLC will need to be uncompressed in ROM for the uploading to VRAM to be quick enough to not cause game slowdown. (Decompressing compressed art has CPU overhead and takes away too many CPU cycles.) The functions in SGDK's sprite engine (in header file
RECOMMENDED DEBUGGING AND ART TOOLS
Finding good software for creating retro graphics, quantizing pixel art into tiles, and reducing the color count to 4bpp can be difficult. Below is a list of the recommended art software to deal with retro graphics, and specialized emulators that allow the user to look at VRAM contents and planes
Art software:
RetroGraphicsToolkit
Da goto tool for quantizing art into tiles, creating optimized tilemaps, and reducing color count for images
Truecolor workflow, FOSS software
Lua scripting
Multi-platform art toolkit
Sega Genesis, Sega Master System, Game Gear
NES
Info links
Irfanview
Generic image viewer/editor, with plugins and very large support for many image file types
Can edit, export, and import palettes, as well as increase/decrease the color count of images, and view color count. Useful for preparing art image files for usage with SGDK's rescomp
FOSS software
Has PNG plugin in order to change color depth while preserving palette order
Info links
PCXpal
Useful software that can convert between several different palette formats.
Useful for converting to/from Megadrive .bin palettes and Irfanview's JASC palette format
Import formats
BMP,GIF,PCX images
GGD, GS*, MSD Genesis emulator savestates
Jasc, Megadrive, MS RIFF, Tile Layer Pro palette files
Export formats
Jasc, Megadrive, and Tile Layer Pro palettes
Info links
asdf
Recommended specialty emulators for VDP debugging
Tutorial on how to use debug pages of Gens emulator and its derivatives (Gens v2.11+)
Gens v11a Re-recording
A modified version of Stef's famous Gens emulator
Has the ability to toggle layers, swap sprite layers
Standard Gens VDP viewer debugger page
AVI video recorder
Info links
Gens KMod
A modified version of Stef's Gens emulator with souped-up Debugger windows. By KanedaFR, from Spritesmind
Live VRAM viewer
Live Sprites viewer
Live Plane Explorer
Live VDP register viewer
Layer toggler
Info links
Exodus emulator
Cycle-accurate, debug, and development focused emulator. Created by Nemesis of Sonic ROM hacking and Spritesmind fame. The Rolls-Royce of Genesis emulation.
Can be useful for debugging lag that only occurs on real hardware
Can be quite resourcing intensive, and requires a very powerful machine to run at usable framerates
VDP VRAM, CRAM viewer
Sprites viewer
VDP Registers viewer
Info links
COMMERCIAL SEGA GENESIS GAMES TO REFERENCE
There are plenty of awesome-looking Sega Genesis games to reference for various techniques and special effects. Such games include:
Streets of Rage series
The Sonic the Hedgehog series
Water palette raster effects
Sprite/tile priority (esp loops and dual-layer chunk system in Sonic 2 & Sonic 3/Knuckles)
High performance, fast, highly-polished game engine
Sprite DPLC
Great level design and art styles (esp. Sonic 3/Knuckles)
Palette cycling effects
Parallax effects
The Adventures of Batman and Robin
Tons of fancy graphical effects
Castlevania Bloodlines
Aladdin
Earthworm Jim series
Smooth animation
The Phantasy Star series
Red Zone
1-bit, smooth, B&W video in the intro
Fake sprite and tilemap SW rotation!
Isometric/Top-down art style
Panorama Cottton (Jap), Street Racer
SNES Mode 7-like graphics, very complex line scrolling and graphical effects
Hard Drivin' and Race Drivin'
3D, SW-rendered polygon graphics
Zero Tolerance and Beyond Zero Tolerance (unreleased)
DOOM-like SW raycaster
Toy Story
Palette raster effects to break the CRAM color limit for static cutscene images
DOOM-like raycaster for 1st-person level
Parallax effects for level geometry in 1st stage with Woody
Star Cruiser (Jap)
3D, SW-rendered polygon graphics
Contra: Hard Corps
Giant Miniboss robot in the first stage is a tilemap with fake tilemap/sprite rotation
The massive homebrew RPG is known as Pier Solar
Great art
Worked on by a team of Genesis fans, gurus, and homebrew developers for several years
Massive 64Mb cartridge
Take note of how different games take advantage of the Genesis' hardware restrictions, and how some games push the hardware to the limits. Streets of Rage and Batman excel with gritty urban locations. The Sonic games have bright, contrasting colors that make it easy to perceive Sonic’s surroundings despite the fast speed. Aladdin and Earthworm Jim have fluid, fun animations that emphasize the characters.
REFERENCES/FOR FURTHER READING
Da Bible of Sega Genesis programming
Official Sega doc about the Genesis
A quick overview of the most important features of the VDP
Dev site from a developer (Fonzie) of Pier Solar
VDP section of Spritesmind forums
Thanks for reading! If you want more, you can read our NES graphics guide here, or check out our SNES graphics guide here!