Downwell Review

logo

Downwell Logo, Downwell website 2016

Developer: Ojiro Fumoto

Publisher: Devolver Digital

Platforms: PlayStation 4, PlayStation Vita, iOS, Android, PC

Genre: Rougelike Platformer

Played on PlayStation Vita

Arcade games focus on the essence of a video game, one or two good mechanics that create everything else. Pac Man eats dots on a screen, Tetris aligns blocks together to destroy them and Asteroids is shooting and avoiding incoming asteroids. Downwell was created by Ojiro Fumoto who was inspired by a quote from video game designer Shigeru Miyamoto.

Japanese Ninento artist and game designe

Shigeru Miyamoto, Time 2016, 7 Fascinating Insights from Nintendo’s Gaming Genius Shigeru Miyamoto, captured on October 21st 2008

“A good idea is something that does not solve just one single problem, but rather can solve multiple problems at once.” Shigeru Miyamoto Interviewed by Eurogamer.net, 31 March 2010

Downwell takes the philosophy of this quote to its logical extreme and has the simplicity of its contemporary’s, but is deceptively skilled based. Downwell will be remembered as the modern arcade game because of the incredible amount of depth, skill and player choice provided from just two game mechanics.

Gameplay

downwell

God is a Geek 2016, “Downwell coming to PS4 and PS Vita this month” May 6th 2016

In Downwell, the player goes down randomly generated levels to the bottom of a well. They encounter enemies, rooms with power ups and a perilous threat at the bottom. Downwell’s excellence comes from how the two actions of jumping and shooting do more than what is expected of them.

Shooting makes the player slightly hover in the air, destroys blockades, creates gems from defeated enemies and has different attack attributes depending on what power up is obtained. Jumping and stomping on enemies without landing builds a combo, landing on the ground or enemies refills the player’s ammo count and landing on the ground stops the combo and rewards gems, ammo and health depending on how high the player’s combo is. The rewards and risks from these multipurpose mechanics direct the player to play at full speed.

download

Downwell artwork by BlueASIS, “Jelly Smash!

This is expanded with randomly generated power ups at the end of a level that add beneficial abilities, such as collecting gems refilling ammo and creating a blast by stomping on enemies. Rooms the player encounters during their descent offer a break from the fast action and have power ups that change the attributes of the shooting attack and give health or ammo. When enough gems are collected, the player enters a gem high that increases the power of their attack, but withers out if the player can’t maintain a constant flow of gems.

This rapid fire decision making is possible because of the art style. Hazards are pure red, enemies indicate they can be jumped on by being predominantly white with a hint of red, walkable and jumpable objects being white and a black background to make colour stand out.

2016-11-24-211827

This makes Downwell have the qualities of iconic arcade games such as Pac Man, but has a layer of mechanical sophistication that is easy to understand, but difficult and engaging to master. When a game like Pac Man is understood, it doesn’t offer a way of adjusting difficulty to suit the player’s mastery and understanding of its mechanics. It only offers more challenge by making enemies faster and more unpredictable. Downwell uses randomly generated power ups that increases the player’s defence or attack capabilities and the player is able to decide on what is best for their skill and situation depending on what they have on hand.

After the end of a playthrough, the player unlocks palette swaps and player styles after collecting a set number of gems. Player styles give unique player native abilities that can make future playthroughs easier or harder depending on their skill level. Palette swaps change the primary colours of the game’s art style. Some palette swaps such as Dirtsnow make reading what’s happening on screen more difficult because of the background colour being different from black.

A problem with power ups is that power ups at the end of a stage are randomly generated. This means the player can’t really customise what playstyle they want and have to replay the game again and again until the right combination is generated. The game could have capitalised on allowing the player to start with a select number of power ups and offer challenges that are unique to the specific power ups the player chooses at the start. While these trappings do not ruin Downwell, it eventually makes repeated long term playthroughs tedious because the player can’t have an optimal loadout from the start.

Value

2016-11-24-140439

Designing a game around one or two game mechanics is an effective way of making one. Downwell is evidence of what happens when just one or two mechanics are developed to their full potential, with gameplay that offers an enjoyable learning curve and depth. Downwell is a short game. While hard mode and palette swaps offer a bit more for the player to achieve, the main game can be finished in fifteen to twenty minutes. This is both Downwell’s strength and weakness, because it makes it an excellent game to pick up and easily get into without a substantial time commitment. But for a player who wants a substantial amount of content and can’t meet that need from replaying and mastering a game’s gameplay, Downwell isn’t going to convince them.

But Downwell has an understanding of how systems and mechanics influence player behaviour that is more sophisticated than most iconic arcade games. Arcade games such as Asteroids and Pac Man had to find the most easily understandable way for people to interact in a virtual space. This meant gameplay had to be about moving around a space and getting a high score.

It made them easily approachable and players would try everything to reach a new high score. But this meant challenge could only increase by making enemies more aggressive, faster and in greater waves. Downwell’s challenge is changeable for the player’s skill. The native abilities from player styles can give more health at the start or make the jump have more float. The player can also decide to take the risk of building a large combo so they restore their health when landing on the ground or build up their gem count to spend on health and ammo items. The skill involved in Downwell comes from how the player survives by making deliberate and intuitive decisions and using the strengths and drawbacks of power ups the player has to decide on at the end of a stage.

It results in a game that is as approachable and fun to play as Asteroids and Pac Man, but has a layer of mechanical mastery that keeps it continuously engaging. After the optimal way to play most arcade games is mastered, it’s gameplay is static and predictable. Downwell is a modernisation of the arcade game because even when the optimal way is mastered, there are still equally valid gameplay choices that are better suited for different levels of skill. It’s creator Ojiro Fumoto wanted to show how solving multiple problems with one solution creates powerful player choice and elegant intuitive design. By following the philosophy of a quote from one of the game industry’s most influential designers, Downwell has solved the arcade game’s issue of static approaches to the problems it presents by using rewards and benefits for jumping and shooting at problems.

What’s great:

  • Phenomenal player decisions and skill from two basic inputs
  • One of the best games iOS and Android has to offer
  • Player styles allow players of different skill levels to find their optimal way of playing
  • Wickedly smooth and responsive controls complement the frantic gameplay
  • Very easy to pick up and get into

What’s okay:

  • The overall length is suitable for it’s gameplay, even if it is incredibly short
  • Not much to achieve besides beating Hard mode and unlocking palettes   

What’s bad:

  • No attempt to capitalise on starting a game with a number of end stage power ups
  • Certain palette swaps make observing what’s happening more difficult
  • Difficult to recommend to people who want substantial content in their games 

How to Make a Platformer in Gamemaker Studio

GameMaker-Studio-Logo

Making 2D platformers in GameMaker Studio involves more than jumping a character up and down. It needs calculations of horizontal movement, Creation Code for a basic checkpoint system and novice developers often stumble because they underestimate what goes into a 2D platformer. While not overwhelming, 2D platformers are a reasonable step up from basic maze and space shooter projects.

After a month of development, I will show you how to make a 2D platformer foundation straight forward enough to develop, but simple enough so you can add your own ideas for a 2D platformer game.

Part 1: Sprites

Make a new project

Create a sprite by pressing this icon

Capture

Make 10 sprites and name them: spr_wall, spr_player, spr_moving_wall, spr_movingwall2, spr_onewayplatform, spr_enemy, spr_emblem, spr_coin, spr_goal, spr_checkpoint

Double click on the sprites and give them the following properties:(The properties can be edited with these GUI interfaces. You can make the sprites anything you want, but its best to work with basic coloured squares)

spr_wall 32×32
spr_player 32×32, 16×16 origin
spr_moving_wall 64×32, 32×0 origin
spr_moving_wall2 64×64, 32×0 origin
spr_oneway_platform 64×32, 32×0 origin
spr_enemy 32×32, 16×16 origin
spr_emblem 32×32
spr_coin 32×32
spr_goal 32×32
spr_checkpoint 32×32, 2 subimages

Part 2: Scripts

Now make a script by pressing this icon

tut-pic-4

In the script, put in the following code:

///—–CHECKPOINT SYSTEM—–///
//—————————-//
if (global.checkpointR != 0)
{
room_goto(global.checkpointR);
}
else
{
room_restart();
}
//—————————-//

//This system needs Creation Code in order to operate
//Make a room called rm_initialise and only put in Creation Code and room_goto_next
//Global Variables are values that carry their functions across all aspects of a game
//The player will never see this room, but is needed in order to make checkpoints work properly
//In the first line, it checks if a checkpoint is activated (if checkpoints are not off)
//The second line enclosed in a curly bracket will spawn the player in the checkpoints position
//The third line checks if the conditions of the first two lines has not been met
//Then the fourth line will spawn the player at the beginning of the level, but only when the conditions of the first two lines has not been met
//In my example, the enemies have room_restart that makes the player start the room over whenever they touch the enemies and have not jumped on top of them
//Because the Creation Code sets the checkpoint system, room_restart or scr_death will achieve the same thing, make the player spawn on an active checkpoint
//But because it restarts the room, global variables for things such as collectables and coins will not be kept intact
//You should use scr_death if you want certain aspects of progress to remain in memory
//Keep in mind that this system is very basic

checkpoint-illustration

Part 3: Objects

After that, make 12 objects and name them: obj_jumprefine, obj_wall, obj_movingwall, obj_movingwall2, obj_onewayplatform, obj_enemy, obj_enemy2, obj_enemy3, obj_emblem, obj_coin, obj_goal, obj_checkpoint

Object 1/12

In obj_jumprefine, edit these values: Depth -1

Put the following code into these events:

Create Event

///—–ESTABLISH PLAYER VARIABLES—–///
//————————————-//
hsp = 0 //horizontal movement
vsp = 0 //vertical movement
grav = 0.5 //force of gravity that pulls the player down to the ground
key_down = 0 //allows players to go down oneway platforms
hsp_carry = 0 //horizontal movement on moving platforms
vsp_carry = 0 //vertical movement on moving platforms (Legacy code, meaning this project ended up not using vertical platforms due to programming difficulties)
acc = 0.50 //the amount a player’s speed revs up until they hit their max
max_speed = 5 //default speed and can be changed by sprinting. Can be any letter key with (keyboard_check(ord(“”)))
jump_number = 1 //how many times a player can jump in the air

//Checkpoint spawning
if (global.checkpointR == room)
{
x = global.checkpointx;
y = global.checkpointy;
}
//When an activated checkpoint exists in a room
//The player spawns in the checkpoints X and Y position
//When a checkpoint isn’t in existence, the player spawns back at the start of the room
//The player’s spawn is affected by falling out of room borders and touching enemies
//————————————-//

Step Event

///—–CONTROLS KEYBOARD INPUT AND GRAVITY—–///
//———————————————-//
if (keyboard_check(vk_right))
{
if (hsp < max_speed) hsp += acc
}

//When the right arrow key is pressed
//The game checks if horizontal movement is less than the maximum movement
//When less than max_speed, hsp adds acc(o.5) for every frame the arrow key is pressed
//This rises until hsp is equal to max_speed(5 or 7)

if (keyboard_check(vk_left))
{
if(hsp > -max_speed) hsp -= acc
}

//When the left key is pressed
//The game checks if horizontal movement is less than the maximum movement
//When less than max_speed, hsp adds acc(o.5) for every frame the arrow key is pressed
//This rises until hsp is equal to max_speed(5 or 7)

if (keyboard_check(ord(“Z”)))
{
max_speed = 7.5
}
else
{
max_speed = 5
}

//When the Z key is pressed
//max_speed is changed to 7.5, making the player move faster because acc now adds more multiples of 0.5 every frame
//When the Z isn’t pressed
//max_speed is set back to normal

running-illustration

if(!keyboard_check(vk_left)&& !keyboard_check(vk_right) || keyboard_check(vk_left) && keyboard_check(vk_right))
{
hsp = 0 + hsp_carry
hsp_carry = 0
}

//To allow the player to stop moving when letting go of a movement key
//The game checks if movement is not pressed or if it is pressed
//Horizontal movement is set to zero when let go or starts it at zero if being pressed
//Previous movement code is responsible for increasing hsp’s value
//! is NOT, && is AND, || is OR
//The hsp carry bracket allows the player to stand and move with a horizontal moving platform

if(place_meeting(x,y+1,obj_wall))
{
jump_number = 1
}
if (keyboard_check_pressed(vk_up)) && (place_meeting(x,y+1,obj_wall))
{
vsp = -12
jump_number -=1
}
if (keyboard_check_pressed(vk_up)) && (!place_meeting(x,y+1,obj_wall)) && jump_number >=0
{
vsp = -12
jump_number -=1
}
if(keyboard_check_released(vk_up) && vsp < 0)
vsp *= 0.5
else
{
vsp +=grav
}

//The game checks if the player is touching or rather 1 pixel above a wall
//If in contact jump_number is set to 1, allowing the jump again after the vsp has been set on input
//When the jump button is pressed
//The jump(vsp) moves the player upwards and subtracts 1 jump_number count
//When jump_number is greater than or equal to 0
//The player can make an additional jump
//This jump can happen on ground or the air and resets after landing
//When the jump key is pressed and released
//It checks if vsp is less than 0
//vsp then equals and multiply by 0.5 until the key is let go
//After these functions have been met or don’t meet conditions
//vsp will equal gravity, that pulls the player down to earth for every frame where a condition hasn’t been met
//———————————————-//

///—–COLLISION AND MOVEMENT CHECKS—–///
//Turn off Solid in your wall object because this paragraph gives superior control over collisions with the player//
//—————————————-//
if(place_meeting(x+hsp,y,obj_wall,))
{
while(!place_meeting(x+sign(hsp),y,obj_wall,))
{
x+=sign(hsp)
}
hsp = 0
}
x += hsp

//When the player’s position meets the wall horizontally
//sign returns 1 or -1 values and checks if left or right meets the wall
//Then if 1 pixel in a space is free, the player keeps moving left or right
//Once the player touches the wall, they stop moving and don’t past through the wall horizontally
//They will then carry on with their current X position

if(place_meeting(x,y+(vsp),obj_wall,))
{
while(!place_meeting(x,y+sign(vsp),obj_wall,))
{
y+=sign(vsp)
}
vsp = 0
}
y += vsp

//When the player’s position meets the wall vertically
//sign returns 1 or -1 values and checks if up or down meets the wall
//Then if 1 pixel in a space is free, the player keeps moving up or down
//Once the player touches the wall, they stop moving and don’t past through the wall vertically
//They will then carry on with their Y position
//—————————————-//

 

///—–GOING DOWN ONE WAY PLATFORMS WHEN STANDING ON THEM—–///
//—————————————–//
key_down = keyboard_check(vk_down)
//When the down key is pressed on a one way platform, the player will fall through it
//The player can also pass through Horizontal and Vertical moving platforms
//—————————————–//

onwayplatform-illustration

Other, Outside Room

///—–FALLING OUTSIDE GAME BORDERS—–///
//—————————————//
room_restart() //When the player goes outside the game borders, the room restarts
//—————————————//

Object 2/12

In obj_wall, edit these values: Children:obj_movingwall, obj_movingwall2, obj_onewayplatform

tut-pic-6

Object 3/12

In obj_movingwall, put the following code into these events:

Create Event

///—–ESTABLISH MOVEMENT PROPERTIES—///
//————————————–//
dir = -1
movespeed = 3
hsp = 0
sprite_index = -1;
//dir is the direction the platform moves in
//movespeed is how fast the platform moves
//hsp is horizontal speed
//Sprite_index allows the player to go through the bottom and sides of the platform
//————————————–//

Step Event

///—–PLAYER COLLISION WITH THE MOVING PLATFORM—–///
//obj_movingwall is a parent of obj_wall, meaning it shares many of obj_wall’s coding properties//
//—————————————————-//
mask_index = spr_moving_wall
hsp = dir * movespeed

//mask_index is the objects collision box
//Horizontal movement is set by direction and movement speed

if (place_meeting(x+hsp,y,obj_wall))
{
while(!place_meeting(x+sign(hsp),y,obj_wall))
{
x += sign(hsp);
}
hsp = 0;
dir *= -1;
}
x += hsp;
if (instance_exists(obj_jumprefine))
{
if (round(obj_jumprefine.y + (obj_jumprefine.sprite_height/2)) > y) || (obj_jumprefine.key_down) mask_index = -1;
else
{
mask_index = spr_moving_wall;
if place_meeting(x,y-1,obj_jumprefine)
{
obj_jumprefine.hsp_carry = hsp;
}
}
}

//When the platform touches a wall
//And they are currently not touching one
//The X position is rounded by sign hsp
//Then the hsp is set to 0
//And the direction is flipped in the other direction
//The platform carry’s on with its X position
//This creates a loop where the platform goes left and right so long as it bounces off a wall
//When a player exists on the platform
//Their Y position is calculated to be above the horizontal platform
//When above the platform, the mask below the platform is off, allowing the player to jump up, down or sideways onto the platform’s centre position
//This is why the platform sprite’s X centre origin is placed in the top middle of the platform (You can change it in the Sprite properties)
//When this condition isn’t met the mask_index is on, allowing the platform to collide with the wall
//When the player is standing on the platform
//Their hsp will equal the platform’s own hsp, allowing them to move with the platform
//—————————————————-//

Draw Event

///—–SHOW SPRITE ON SCREEN—–///
//——————————–//
draw_sprite(spr_moving_wall,0,x,y);
//The objects sprite is shown on screen
//——————————–//

Object 4/12

In obj_movingwall2, put the following code into these events:

Create Event

///—–ESTABLISH MOVEMENT PROPERTIES—–///
//————————————–//
dir = 1
movespeed = 1
vsp = 0
sprite_index = -1
//dir is the direction the platform goes in (up and down)
//movespeed is how fast the platform goes
//vsp is vertical movement
//sprite_index sets the sprite subimage

Step Event

///—–MOVEMENT AND COLLISION OPERATIONS—–///
//Legacy code that does not work properly
//——————————————–//
vsp = dir * movespeed
mask_index = spr_moving_wall2
if (place_meeting(x,y+vsp,obj_wall))
{
while(!place_meeting(x,y+sign(vsp),obj_wall))
{
y += sign(vsp);
}
vsp = 0;
dir *= -1;
}
y += vsp;
if (instance_exists(obj_jumprefine))if (round(obj_jumprefine.y + (obj_jumprefine.sprite_height/2)) > y) || (obj_jumprefine.key_down) mask_index = -1;
else
{
{
mask_index = spr_moving_wall2
if place_meeting(x,y-1,obj_jumprefine)
{
obj_jumprefine.vsp_carry = vsp;
}
}
}
//——————————————–//

Draw Event

///—–SHOW SPRITE ON SCREEN—–///
//——————————–//
draw_sprite(spr_moving_wall2,0,x,y);
//The objects sprite is shown on screen
//——————————–//

Object 5/12

In obj_onewayplatform, put the following code into these events:

Create Event

///—–ESTABLISH ONE WAY PLATFORM VARIABLES—–///
//———————————————–//
sprite_index = -1
//sprite_index is responsible for affecting the collision box
//By default, -1 turns off the collision box
//the Draw Event, separate from this code script allows players to see the object sprite
//The Step Event affects if the player can stand on top of the platform by turning the sprite_index on and off

Step Event

///—–PLAYER COLLISION WITH ONEWAY PLATFORM—–///
//————————————————//
//Check for player existing in the game to prevent death script conflict and crashes
if(instance_exists(obj_jumprefine))
{
if (round (obj_jumprefine.y + (obj_jumprefine.sprite_height/2)) > y) || (obj_jumprefine.key_down) mask_index = -1
else mask_index = spr_oneway_platform
}
//When the player exists in the game
//The sprite’s foot is checked
// when its greater than the position of the one way platform
//round turns numbers into integers to ensure whole numbers are caculated
//mask_index is turned on, letting the player stand on top of the platform’s origin

Draw Event

///—–SHOW ONEWAY PLATFORM SPRITES ON SCREEN—–///
//————————————————-//
draw_sprite(spr_oneway_platform,0,x,y)
//Shows Oneway platfrom’s sprite
//————————————————-//

Object 6/12

In obj_enemy, put the following code into these events:

Create Event

///—–ESTABLISH ENEMY VARIABLES—–///
//————————————//
state = e_state.idle//allows the enemy to move once the player is close enough
dir = -1;//the direction the enemy moves
movespeed = 2;//the speed the enemy moves at
grav = 0.5;//the force of gravity dragging the enemy down to the ground
hsp = 0;// horizontal movement
vsp = 0;//vertical movement
//————————————//

Step Event

///—–ENEMY LOGIC AND COLLISION—–///
//————————————//
switch (state)
{
case e_state.idle:
{
hsp = 0;
vsp = (min(7,vsp+0.5));
if (distance_to_object(obj_jumprefine) < 384) state = e_state.chase;
}
break;
case e_state.chase:
{
dir = sign(obj_jumprefine.x – x);
hsp = dir * 2;
vsp = (min(7,vsp+0.5));
if (distance_to_object(obj_jumprefine) > 416) state = e_state.idle;
}
break;
}
if (place_meeting(round(x+hsp),round(y),obj_wall))
{
while(!place_meeting(round(x+sign(hsp)),round(y),obj_wall)) x += sign(hsp);
hsp = 0;
}
x += hsp;
if (place_meeting(round(x),round(y+vsp),obj_wall))
{
while(!place_meeting(round(x),round(y+sign(vsp)),obj_wall)) y += sign(vsp);
vsp = 0;
}
y += vsp;

//The enemy has their state set to idle
//State machines are isolated forms of code that can be called upon at any time
//They are a useful advanced rescource for making A.I, complex mechanics and menus
//In idle, the enemy is still and is affected by gravity
//When the player comes into a close distance to the enemy, the state changes to chase
//The previous state is replaced with the new activated state
//The enemy moves to the player’s X posistion at a speed of 2
//The enemy is still affected by gravity
//Once the player has enough distance away from the enemy
//The enemy’s state goes back to idle and the chase state is lost until activated again
//The rest is collision code with the wall that rounds caulations to whole numbers
//————————————//

enemy-a-i-illustration

///—–PLAYER ABILITY TO JUMP ON AND DEFEAT ENEMIES—–///
//——————————————————-//
if(place_meeting(x,y,obj_jumprefine))
{
if(obj_jumprefine.y < y – 20)
{
with(obj_jumprefine) vsp = -vsp
instance_destroy()
}
else
{
room_restart()
}
}

//When the player is touching an enemy
//The player has their Y posistion checked to see if its a set number less than the enemies own Y posistion
//When less than the enemies Y posistion, the player will bounce upwards off the enemy and kill it
//The player’s bounce is equal to how much vsp was caculated during the check
//If falling from a great height, the player will have a great bounce upwards and vice versa
//If that check isn’t met, the player is beaten by the enemy and the room restarts
//In my example, the enemies have room_restart that makes the player start the room over whenever they touch the enemies and have not jumped on top of them
//Because the Creation Code sets the checkpoint system, room_restart or scr_death will achive the same thing, make the player spawn on an active checkpoint
//But because it restarts the room, global variables for things such as collectibles and coins will not be kept intact
//You should use scr_death if you want ceartin aspects of progress to remain in memory
//——————————————————-//

enemy-stomp-illustration

Outside Room

///—–FALLING OUTSIDE GAME BORDERS—–///
//——————————-//
instance_destroy()//When outside the room’s borders, the enemy is destroyed
//——————————-//

Object 7/12

In obj_enemy2, edit these values: Children: obj_enemy3

Put the following code into these events:

Create Event

///—–ESTABLISH ENEMY VARIABLES—–///
//————————————//
dir = -1//the direction the enemy moves
movespeed = 2//the speed the enemy moves at
grav = 0.5//the force of gravity dragging the enemy down to the ground
hsp = 0// horizontal movement
vsp = 0//vertical movement
fearofheights = 0//allows obj_enemy3, a child of obj_enemy2 to move without falling off the ground
//————————————//

Step Event

///—–ENEMY LOGIC AND COLLISION—–///
//————————————//
hsp = dir * movespeed;
vsp += grav;

//hsp is caculated by direction and movement speed
//vsp is gravity, the force that pulls objects down to the ground

if (place_meeting(x+hsp,y,obj_wall))
{
while(!place_meeting(x+sign(hsp),y,obj_wall))
{
x += sign(hsp);
}
hsp = 0;
dir *= -1;
}
x += hsp;

//When touching walls
//The enemy goes in the opposite direction
//They retain their X posistion

if (place_meeting(x,y+vsp,obj_wall))
{
while(!place_meeting(x,y+sign(vsp),obj_wall))
{
y += sign(vsp);
}
vsp = 0;
if (fearofheights) && !position_meeting(x+(sprite_width/2)*dir, y+(sprite_height/2)+8, obj_wall)
{
dir *= -1;
}
}
y += vsp;

//When moving across walls and near an edge
//The enemy’s sprite is checked to see if it’s 8 pixels away from changing its Y position
//If the enemy is 8 pixels away from going off a edge, the enemy will have its direction changed before they fall off
//They retain their Y position
//This code only affects obj_enemy3 that inherits obj_enemy2’s properties
//————————————//

///—–PLAYER ABILITY TO JUMP ON AND DEFEAT ENEMIES—–///
//——————————————————-//
if (place_meeting(x,y,obj_jumprefine))
{
if (obj_jumprefine.y < y-20)
{
with (obj_jumprefine) vsp = -vsp;
instance_destroy();
}
else
{
room_restart();
}
}

//When the player is touching an enemy
//The player has their Y posistion checked to see if its a set number less than the enemies own Y posistion
//When less than the enemies Y posistion, the player will bounce upwards off the enemy and kill it
//The player’s bounce is equal to how much vsp was caculated during the check
//If falling from a great height, the player will have a great bounce upwards and vice versa
//If that check isn’t met, the player is beaten by the enemy and the room restarts
//In my game, the enemies have room_restart that makes the player start the room over whenever they touch the enemies and have not jumped on top of them
//Because the Creation Code sets the checkpoint system, room_restart or scr_death will achieve the same thing, make the player spawn on an active checkpoint
//But because it restarts the room, global variables for things such as collectables and coins will not be kept intact
//You should use scr_death if you want ceartin aspects of progress to remain in memory
//——————————————————-//

Object 8/12

In obj_enemy3, put the following code into these events:

Create Event

tut-pic-5Drag and Drop in Control tab

///—–ABILITY TO NOT FALL OFF EDGES WHEN MOVING LEFT AND RIGHT—–///
//————————————————————————//
fearofheights = 1//Allows the enemy to not fall off edges
//Affects only obj_enemy3
//————————————————————————//

Object 9/12

In obj_emblem, put the following code into these events:

Collision Event with obj_jumprefine

///—–PLAYER INTERACTION WITH EMBLEM—–///
//—————————————//
instance_destroy()
//When the player touches the emblem, the emblem vanishes
//It does nothing and is there to see the basic idea of collectables in action and how they affect player behaviour
//—————————————//

Object 10/12

In obj_coin, put the following code into these events:

Collision Event with obj_jumprefine

///—–PLAYER INTERACTION WITH COIN—–///
//—————————————//
instance_destroy()
//When the player touches the coin, the coin vanishes
//It does nothing and is there to see the basic idea of collectibles in action and how they affect player behaviour
//—————————————//

Object 11/12

In obj_goal, put the following code into these events:

Collision Event with obj_jumprefine

///—–PLAYER INTERACTION WITH GOAL—–///
//—————————————//
room_goto_next()
//When touching the goal, the player is sent to the next room
//This order can be arranged simply by having rooms ordered top to bottom in the room folder
//e.g rm_initialize, rm_level1, rm_level2, rm_testing
//—————————————//

Object 12/12

In obj_checkpoint, put the following code into these events:

Create Event

///—–ESTABLISH VISUAL ELEMENTS—–///
//————————————//
image_index = 0
image_speed = 0
//image_index sets the sprite subimage drawn on the screen
//image_speed sets how quickly the sprite shows its animation frames
//In this suitation, the checkpoint will rapidly flash without its speed set to 0
//————————————//

Step Event

///—–CHECKPOINT REACTION TO PLAYER—–///
//—————————————-//
if (place_meeting(x,y,obj_jumprefine))
{
global.checkpoint = id;
global.checkpointx = x;
global.checkpointy = y;
global.checkpointR = room;
}
if (global.checkpointR == room)
{
if (global.checkpoint == id) image_index = 1; else image_index = 0;
}
//When the player touches a checkpoint
//The checkpoint sets its global variables
//== room checks for the existence of a activated checkpoint inside a room to reduce repetition
//When in existence, the specific checkpoint is identified
//the checkpoints subimage is switched so the player sees that it is working
//When not in existence or a new existence is found, the subimage for the previous existence goes back to normal
//—————————————-//

Part 4: Rooms

Finally, make 3 rooms and name them the following: rm_initialise, rm_level1, rm_level2

Room 1/3

In rm_initialise, enter Creation Code in the Settings tab and put in the following:

///—–ESTABLISHING GLOBAL SYSTEM VARIABLES—–///
//———————————————–//
global.checkpoint = noone;
global.checkpointR = 0;
global.checkpointx = 0;
global.checkpointy = 0;
room_goto_next();
//global variables are values that are always accessible to every aspect of a game, instead of normal values that only affect the object their made in
//checkpoint is the ID of a currently active checkpoint. It’s set to noone so when a checkpoint is activated, GML does not get confused over the existence of multiple checkpoints
//checkpointR is what room the player is currently in
//checkpointX is the left and right position of the checkpoint
//checkpointY is the up and down position of the checkpoint
//When a checkpoint is activated, these global variables change to match its location values
//After this system is set, the game goes straight to the first interactable room
//———————————————–//

Room 2/3

In rm_level1, go into the Views tab

Tick “Enable the use of Views”

Have View 0 selected

Tick “Visible when room starts”

Set W to 650, H to 600 in “View in room”

Set W to 1024, H to 768 in “Port on screen”

Set Hbor and Vbor to 999 and select obj_jumprefine in “Object following”

In the Settings tab, set “Speed” to 60. The size and length of the room can be changed with “Width” and “Height”

In the Objects tab, select obj_wall in “Object to add with left mouse” and place it in the room. Add and create the objects you want in the room to your heart’s content

Room 3/3

Repeat for rm_level2

Upon finishing this example your game should have pixel perfect wall collisions, movement with weight that creates a feeling of greater control, a double jump for the ground and air that resets on landing, the ability to defeat enemies by jumping on top of them and die and respawn when touching them, checkpoints that start players at their position when activated, horizontally moving platforms that carry the player with them, the ability to freely run and walk by pressing down a run key, specific platforms the player can pass through downwards and jump back onto and collectable coins and emblems for leading players like breadcrumbs and expanding into bonus content.

My example isn’t perfect however. The way horizontal control is made means that a sliding effect can happen with a very specific use of the run button and move controls. Vertical platforms have also proven in the end to be out of my abilities. If you are seeking vertical platform solutions, you will likely have to use other resources such as ZGB’s Moving Platforms.

I hope my example has helped you in your projects. Do not hesitate to point out what is wrong with my example and I hope this foundation will allow you to make the product the video game industry deserves.

A possible solution to Overwatch’s Infinite Loading Bug

 

overwatch_hanamura_jpg

In Blizzard’s multiplayer shooter, a crippling bug can inflict players and render the game unplayable. It it’s commonly known as the Infinite Loading Loop. This bug happens when players are waiting for a game map to load and cannot get past the loading screen.

The bug breaks the game because players cannot even access training modes that are separate from multiplayer modes. It also leads to terrible effects on players as inactive players will eventually be kicked out of a match. If kicked out enough through a error players have no control over, they are penalised with a 75% reduction in experience points until their Games Played and Games Completed ratio returns to normal.

There is no absolute solution to this serious problem because the game loads an environment map while internet connections go through Battle.net’s DRM (Digital Rights Management) that verify players are connected to Blizzard’s servers. This guide shows a solution that has worked for me in my experience with the Infinite Loading loop and may work for your circumstances.

Press the Windows key

Search  firewall

Select “Allow an app through Windows Firewall”

Click on “Change Settings” (This step assumes you have administrative rights)

Scroll down until you find “Overwatch Application”

Tick the Private checkbox and leave the Public checkbox unticked

Press the “Ok” button on the bottom of the firewall screen

Exit the firewall window

Open up Overwatch and enter a training map. The map should load as normal and all games modes should not experience the loading bug. This possible fix opens up the games port communication with Blizzard’s servers.

When Private is not ticked off, the firewall prevents the port from communicating with the servers because it thinks it’s a malicious payload. Do not tick the Public checkbox because only your PC’s protocol has to forward a connection to Blizzard’s servers. You don’t want other devices finding your PC every time you are playing Overwatch.

I hope this guide helps fix your encounter with the Infinite Loading Loop. Have fun with one of the year’s greatest games.

 

How to Make Basic Invincibility Frames in GameMaker Studio

GameMaker-Studio-Logo

In video games, invincibility frames are the period of time when a player is invulnerable to a game’s hazards. They allow the player to make a mistake and have enough time to quickly move away from hazards. Without invincibility frames, moments of high challenge become frustrating for players that don’t have a high level of skill. While not every game requires invincibility frames, they are a feature that grants players a margin of error for how many times they can make a mistake.

To start, create 3 sprites and name them Spr_Player, Spr_Wall and Spr_Enemy1.

Tutorial Pic1

Then create 3 objects and name them Obj_Player, Obj_Wall and Obj_Enemy1

Tutorial Pic2

Select Obj_Wall and have Solid turned on

Tutorial Pic3

Then open up Obj_Player and put in these events:

Tutorial Pic4

Now make a sound file with the sound icon.

Tutorial Pic8

Select an MP3 file from your computer and in Target Options, Set it to Stereo and 16 bit.

In the Create event, enter the Control tab on the right. In the Variables section, select Set Variable and put in the following:

Tutorial Pic5

In the Alarm 0 event, put in the following:

Tutorial Pic6

In the Step event, put in the following:

Tutorial Pic7

In the Collision event with Obj_Enemy1, put in the following:

Tutorial Pic9

In the Draw event, put in the following: (For the code icon, put in image_alpha = Flash)

Tutorial Pic10

Once a room has been made and these 3 objects are placed in that room, the player should flash when coming into contact with the enemy and a sound effect will play. Do not hesitate to point out flaws and inaccuracies with this tutorial and I hope this has helped your title in progress.

How to make player movement for a platformer in Gamemaker Studio

GameMaker-Studio-Logo

(The following method is borrowed from Animator XP’s “Game Maker Studio Tutorial: Arcade Platformer Part 1 (Movement)”

1.Create a sprite, name it spr_player

Capture

2.Open up the sprite and select “Modify Mask”

Capture1

3.In Bounding Box, set it to “Full image”

Capture2

This allows the player object to have the best collision possible with platforms.

4.Create an object, name it obj_player

Capture3

5.Open up the new object and select “Add Event” in the events tab

Capture4

6.Select “Create”

Capture5

7.In the “Actions” tab, select “Control” and in “Code” drag the document icon into “Actions”

Capture6

Capture7

8.In the code window, type in the following:

room_speed = 60 // sets the game’s frame rate. (FPS) 60 is the ideal FPS for games.

jumped = false //the player is unable to jump until an actions changes it to true.

9.Then in obj_player, select “Add Event” in the events tab

10.Open up the “Alarm 0” event

Capture8

Repeat step 7

11. Type in the following:

jumped = false // this determines if the player is able to jump or stay on the ground.

This is changed in the “Step” code. The create event makes this variable and the alarm triggers when a player input changes it to false.

Repeat step 9

12. Open up the “Step” event

Capture9

Repeat step 7

13. Type in the following:

if(keyboard_check(vk_left)) //when the left key is pressed
{
if(place_free(x-5,y))//this checks if 5 pixels to the left are open space
{
x-=5//speed of movement.
}
}

if(keyboard_check(vk_right)) //when the left key is pressed
{
if(place_free(x+5,y))//this checks if 5 pixels to the left are open space
{
x+=5//speed of movement.
}
}

if(keyboard_check_pressed(vk_up))//when the up key is pressed
{
if(!place_free(x,y+5))//this checks if 5 pixels up and down are open space.
{
jumped = true//the alarm changes to true.
alarm[0] = 15// jump into the air. Affects how high the player jumps.
}
}

if(jumped == false)//when the alarm’s false, trigger the falling code.
{
//Fall code:
if(place_free(x,y+8))
{
y+=8//affects how fast the player falls.
}
else
{
if(place_free(x,y+2))
{
y+=2
}
}
}

else
{
//Jump code:
if(place_free(x,y-alarm[0]))
{
y-=alarm[0]//the alarm changes to false.
}
else
{
alarm[0] = 1
{
y-=0
}
}
}

14.Repeat step 1 and 4, name it spr_wall and obj_wall

15. Open up obj_wall and tick “Solid”

Capture10

16. Make a room

Capture11

17. Make a basic level and place obj_player in it.

Capture12

Capture13

The player should stand on the ground, fall when jumping and not pass through walls.

This method is good for platform controls that feel fluid and responsive on a basic level, but it has flaws. “Place_free” checks if a set number of pixels are open space, meaning this method is not ideal if your level design consists of pixel perfect platforms. Animation with player movement is also limited because “Keyboard_check” responds to the specific input.

Say you pressed left and the jump button together. Players will see the left key animation and not the jump key animation unless it’s the only button pressed.

E.g

if (jumped == true) //checks if jump is true

{

sprite_index = spr_playerjump //jump animation displays on screen

}

if (jumped == false) //checks if jump is false

{

sprite_index = spr_player // idle animation displays on screen

}

if(keyboard_check(vk_left)) //checks if the left key is pressed

{

sprite_index = spr_playerleft // left movement animation displays on screen

if(place_free(x-5,y))

{

x-=5

}

}

if(keyboard_check(vk_right)) //checks if the right key is pressed

{

sprite_index = spr_playerright // right movement animation displays on screen

if(place_free(x+5,y))

{

x+=5

}

}

If you require a method with complete and fully robust customization, use the method on GameMaker Tutorials.com

I hope this method has helped you with your title in progress. Do not hesitate to point out faults with this tutorial and take care.

References:

Gamemaker Tutorials.com “Platformer Basics [Article]” May 4, 2014 viewed on 22nd May 2016 http://gamemakertutorials.com/?p=383

AnimatorXP (May 8th 2016)”Game Maker Studio Tutorial: Arcade Platformer Part 1 (Movement)” retrieved from https://www.youtube.com/watch?v=sx50CKhfT88

Enhanced Pictures From Photoshop

Some time ago I sat down at my table, dulled by the exhaustion of a long hard day. I was granted the task of enhancing photographs with Photoshop and with inspiration taking advantage of my lack of experience, I produced these transformed creations.

Crystal Galaxy

IMG_8052 PS Keep

The Honeycomb Meteor

IMG_8090 PS

Divided from reality

IMG_8073 PS

A delicious Poison

IMG_8070 PS