Mega Drive SGDK Megarunner

Learn how to make an endless runner for the Sega Mega Drive using SGDK! I highly recommend working through the Megapong Tutorial first, as that explains a lot of the basics of MD coding.

Megarunner 1 - The Framework

Welcome to a new tutorial series on Mega Drive development! Here we’ll be creating a Mega Drive game from scratch using SGDK, the Sega Genesis Development Kit. And this is what we’ll be working on:


I call it Megarunner. It’s an endless runner-type game where you jump over obstacles to gain points. The game ends when you hit one of the obstacles. It’s a simple concept and thus a good way to learn about some new concepts of Mega Drive programming like scrolling and animation!

It is highly recommended that you check out the tutorial for Megapong first, as that tutorial leads you through setting up a development environment and teaches you the basics of Mega Drive programming. Concepts and ideas already explained in Megapong won’t be repeated in as much detail here, so it’s a good idea to learn the basics first.

And as a final note, this game will use assets created by Jonathan for his Game Creator’s Pack, so shoutouts to him!

And with all that out of the way, let’s get coding!

Setting up a project

First we’ll create a project and set up the general framework along with some functions that we’ll use throughout. This tutorial already expects you to have SGDK installed and a development environment up and running, so if you haven’t, work through the Megapong tutorial first! I feel like I’m saying that a lot.

Create a new project, either by cloning/downloading my template or by using your own that you might have created (with a .vscode folder already in it). Call it “megarunner”. Or whatever you want, really. Then open the project in your IDE (ideally VSCode).

Now let’s add stuff to main.c! First, at the very top, include the string header:

#include <string.h>

We’ll need it for some string manipulations later. Now below that we’re gonna add some variables. I’d recommend labelling this code block using a comment, so that you won’t end up with a pile of random variables at the end of the project.

/*General stuff*/
const char msg_start[22] = "Press START to Begin!";
const char msg_reset[22] = "Press START to Reset!";
bool game_on = FALSE;

The two message constants will store the strings we’ll display before and after the game. game_on will track whether the game is currently running or not. Note that C doesn’t actually have a bool type, but SGDK defines one for us to make things easier (with TRUE == 1 and FALSE == 0 respectively).

Next, let’s define two small helper functions. The first will display a line of text in the center of the screen, while the second will delete that line. We’ll use them to display (and delete) the strings we’ve just defined.

void showText(char s[]){
	VDP_drawText(s, 20 - strlen(s)/2 ,10);

void clearText(){

A quick reminder here that the text functions in SGDK use tiles as their unit of measurement, not pixels. So VDP_clearText(0,10,32) will delete a total of 32 characters (= tiles) in the 10th tile row from the very left of the screen.

Now we have an easy way to display and delete text without having to fiddle with the positioning every time. Next, we’ll define startGame() and endGame(), two functions that will handle the beginning and end of our game.

void startGame(){
	if(game_on == FALSE){
		game_on = TRUE;

void endGame(){
	if(game_on == TRUE){
		game_on = FALSE;

As you can see, these functions toggle the game_on variable, while endGame() also displays our game over message using the function we just created. Told you it would be useful!

Alright, one more thing before we get to the main part of our game: We’ll have to create a callback function that will process our joypad input. We’ll only be using one joypad and two buttons, START and C. So add the following function:

void myJoyHandler( u16 joy, u16 changed, u16 state)
	if (joy == JOY_1)
		/*Start game if START is pressed*/
		if (state & BUTTON_START)
			if(game_on == FALSE){
		if (state & BUTTON_C)

As you can see we’re already adding a bit of functionality: If the player presses start, startGame() is called, which makes sense if you think about it. We’ll find out what the C-button does later on.

Alright, now we’ll close things off with the main event in the form of main(). This of course is the function that will be called on start and contains all our actual game code. For now we’ll just define the basic stuff, so it’s not much to look at.

int main()
	JOY_setEventHandler( &myJoyHandler );


		if(game_on == TRUE){


	return 0;

This is all pretty much boilerplate stuff. We initialize the joypad and tell SGDK to use myJoyHandler as our callback function. Then we display our msg_start message using that handy showText function again. Finally we begin the main game loop with while(1). We’ll have a section with things that should only happen when game_on is TRUE, but VDP_waitVSync(); always needs to be called every frame.

Phew, that was quite a lot of code, but it’ll give us a good foundation to make our game. If you compile now you should see our string Press START to Begin! on screen and if you press Start on your controller it should go away. So far so good!

Stay tuned for the next installment where we’ll put some tiles on screen using a nifty new function. Thanks for reading and stay excellent!

If you have any questions, comments or criticism, post them in the comments below or reach out to me on Twitter @ohsat_games! Special thanks to Stephane Dallongeville for creating SGDK and everyone in the SGDK Discord for their help and keeping the dream alive!

Download the source code

All patrons on Patreon get the complete source code for this tutorial, as well as other perks such as early access! Become a Patron!
Just Want to Buy Me a Coffee?

Check out the rest of this tutorial series!

  • Megarunner 1 - The Framework
  • Megarunner 2 - Tiles
  • Megarunner 3 - Scrolling
  • Megarunner 4 - Player and Obstacles
  • Megarunner 5 - Jumping Math
  • Megarunner 6 - Collision and Score
  • Megarunner BONUS - Tile Scrolling
  • Get Words in Your Inbox!

    Be oldschool and sign up for my newsletter to occasionally get updates and ramblings! Just enter your email address, prove you're not part of Skynet and you're good to go!

    I will not send you spam or sell/give your email address to someone else.  You can of course unsubscribe at any time. By clicking the subscribe button above, you confirm that you have read and agreed to our privacy policy.

    By using the Disqus service you confirm that you have read and agreed to the privacy policy.

    comments powered by Disqus

    Make a Space Shooter for the Mega Drive!

    February 24, 2020
    Mega Drive Ramblings

    Patreon Revamps

    January 28, 2020
    Mega Drive Ramblings Patreon

    New SGDK Tutorial: Megarunner!

    November 4, 2019
    Mega Drive Ramblings