Discord Minesweeper

Create games of minesweeper using Discords Spoiler Tags.

Usage

const mines = require('discord-minesweeper');

let output = mines(X, Y, mines, char, formatted);

Parameters

ParameterDescription
XWidth
YHeight
minesNumber of mines
charCharacter to use internally to represent bombs. If formatted == false, this will be used to represent bombs in the output array.
formattedWhether to output as a formatted message (with line breaks and emojis) or as a 2D array.

Example

const Discord = require('discord.js');
const client = new Discord.Client();
const mines = require('discord-minesweeper');

...

client.on('message', msg => {
  if (msg.content === '!mines') {
    msg.author.send(mines(14, 14, 20, 'X', true));
  }
});

Browser Example

If you want to run this in the browser to create text that you can copy and paste.

Browser Example

Links

PROCJAM 2018

PROCJAM 2018 is running from October 20th 2018 at 11:00 AM to October 29th 2018 at 12:00 PM NZST. 

What is procjam?

#procjam is a jam about making generative software – computer programs that make things when you run them, like art, music, games, stories, wallpapers, recipes, poetry or anything else you can think of.

https://itch.io/jam/procjam @ 2/10/2018

You can start before the start date, and finish after the end date.

You can use existing code/art/writing/anything or even continue an existing project. Feel free to add something generative to a game you’re making and submit that!

We welcome all kinds of submissions. No entry is too small or too big for this jam. Whether this is your first generator of your hundredth, we welcome what you’ve made, and we all want to see it.

PROCJAM has no winners and no losers. We try to highlight and celebrate all our entries, and everyone who enters will get featured in Jupiter Hadley’s YouTube compilation of the jam!

https://itch.io/jam/procjam @ 2/10/2018

My Submission

https://phush.itch.io/wave

Initial Concept Project

I used my dynamic cuboid terrain to create this procedurally generated terrain, for a pixel style rpg, adventure/fantasy game.

The terrain is a heightmap which is generated using Perlin Noise and is stored as a 2D array of floats. The cubes that are generated are then mapped onto a point in the heightmap and as the player moves, some points get loaded in from the heightmap onto the cubes and other points get removed. This resulted in the functionality below:

However it would be hard to make a decent procedurally generated rpg in a short amount of time so I switched things up a bit.

The terrain made a pretty convincing wave, so I tested out using semi-transparent blue cubes, ground underneath that and linear terrain shift. This is what it looked like:

From here the idea was to either make a game similar in genre to Galaga or Raiden, or make an endless deathmatch arena style game.

Beta v0.3.0 Release

Download here

Press V to switch between modes

Camera/Movement Modes:

Translational Orthographic:

Controls:

  • WASD movement
  • Mouse to aim
  • Left click to fire
  • 0,1,2 to change ammo

Rotating Perspective:

Controls:

  • WS – Movement
  • AD – Rotation
  • Mouse to aim
  • Left click to fire
  • 0,1,2 to change ammo

v0.4.0 Enemy Test Release

Download

Press Escape to pause, game auto pauses when you are below 0 hp and take damage (no death mechanic) and can be resumed after taking lethal damage.

Ammo

0 – Shell

Fire a shell horizontally. If aimed at an enemy it will aim for their centre of mass otherwise it will aim for 1 metre above the surface of the water.

1 – Homing Missile

Tracks and homes in on the target if an enemy is being hovered over by the mouse when it is fired. Otherwise behaves like a shell with a thruster on it.

2 – Torpedo

Glides along the surface of the water.

Wave System

At the end of each wave the game will randomly decide to increase the difficulty in one of three ways:

  • Increased enemy hp
  • Increased enemy damage
  • An additional enemy

Enemies

Balloon

This little bad boy hovers at a stationary position and shoots at you.

FireWise

Error, image could not be displayed

FIREWISE is a short 2D action game with one small mechanic removed: the ability to stop moving.  This game was made by a team of University of Auckland students for the 2018 48 hour GMTK Game Jam.

Due to switching from the Godot engine to Unity mid jam, we didn’t get anywhere near as much content or mechanics out in the game as we would have liked, though we are happy with with the finished product.

Links

Itch.io: https://uoa.itch.io/firewise
Game Jam Submission: https://itch.io/jam/gmtk-2018/rate/300181
GitHub: https://github.com/nofishleft/FireWise-Unity

Unity Camera Shake

For camera shake I start with a variable (which I’ll call trauma), which we decrement linearly over time, and accepts floating point values between 1 and 0. Our camera shake will be proportional to trauma squared or cubed.

I always try to avoid rooting values for performance reasons and this allows us to easily decrement the amount of camera shake of time, without having to root anything and allows a visible distinction between low, medium and high levels of camera shake.

To implement this we multiply our shake (trauma^2/^3) by our maxOffset and a randomly generated number. We get something like this:

offsetX = maxOffset * trauma^2 * SomeRandomNumber
offsetY = maxOffset * trauma^2 * AnotherRandomNumber
angle = maxAngle * trauma^2 * AnotherRandomNumber

There are two problems with this;

  1. It is frame rate dependent and not time based. This means that system performance will affect the visible camera shake, and this shake is not slow motion compatible and won’t work with tools like Chronos.
  2. Jerky camera movement, the camera sometimes appears to teleport between positions, rather than move between them over several frames.

This can be solved with Perlin Noise. With Perlin Noise, we can create camera shake that is time based and smoothed.

offsetX = maxOffset * trauma^2 * PerlinNoise(seed1,time)
offsetY = maxOffset * trauma^2 * PerlinNoise(seed2,time)
angle = maxAngle * trauma^2 * PerlinNoise(seed3,time)

We use different seeds for the each so that each motion is independent. To control how quickly the camera moves, replace your time with your time multipled by a speed constant. It should be noted that here you don’t want to use your deltaTime, but rather the current time/cumulative time.

You should also take care to preserve the original x, y values and the angle value. When you calculate your offset you want to add that to your base location/rotation, otherwise you will have your camera going everywhere. When moving and adjusting your camera in your script, you should alter these base preserved values

Translational vs Rotational

In 2 dimensions, pure translational camera shake looks alright, and pure rotational shake looks a bit off. By combining these in certain amounts we can create a pretty nice camera shake effect.

3 dimensions however, is different. In 3D, translational camera shake can have all sorts of bad effects, it can cause our camera to clip through walls and objects, make it hard to see and focus on objects, and cause motion sickness, especially in first person 3D games. Rotational shake however is usually very effective in 3D, and as it doesn’t change the position of the camera, you don’t have to worry about the camera clipping through walls.

A C# Unity Implementation/Example

float trauma = 0f;
Vector3 preserveOffset;
Vector3 preserveAngle;

public float maxAngle = 10f;
public float maxOffset = 1f;

public float shakeTranslationSpeed = 1f;
public float shakeRotationSpeed = 1f;

public float traumaLossRate = 0.01f;
public bool reduceTrauma = true;

float seed1;
float seed2;
float seed3;

public void addTrauma (float increment) {
	trauma = Mathf.Clamp(trauma + increment, 0, 1);
}

void Start () {
	preserveOffset = transform.localPosition;
	preserveAngle = tranform.localEulerAngles.z;
	
	//Seeds should be offset from each other Random.Range,
	//and non-overlapping ranges there is no way for two
	//seeds to be similar
	seed1 = Random.Range(300f,400f);
	seed2 = Random.Range(150f, 250f);
	seed3 = Random.Range(0f,100f);
}

void Update () {
	if (trauma > 0) {
		float shake = trauma^2;
		//translational camshake
		float offsetX = maxOffset * shake * Mathf.PerlinNoise(seed1, shakeTranslationSpeed*Time.time);
		float offsetY = maxOffset * shake * Mathf.PerlinNoise(seed2, shakeTranslationSpeed*Time.time);
		transform.localPosition = preserveOffset + new Vector3(offsetX,offsetY,0);
		//rotational camshake
		float angle = maxAngle * shake * Mathf.PerlinNoise(seed3, shakeRotationSpeed*Time.time);
		transform.localEulerAngles.z = preserveAngle + angle;
		
		//Allows for the option to have constant
		//non-decreasing cam shake without the need to 
		//continuously reapply trauma
		if (reduceTrauma) trauma = Mathf.Clamp(trauma-traumaLossRate*Time.deltaTime,0,1);
    }
}

Links

Unity Perlin Noise Documentation