The Game Plan: Getting Started

Leave a comment Standard
file0001764062159

Your game design can run fairly smoothly or it can be a continuous cesspool of hardships and setbacks and pain points. In the next few series of posts I’m going to try and help walk you through the process of getting your game up and off the ground, from what you’re envisioning in your head to an actual working version. So, let’s get started.

1. Get It Out Of Your Head

It’s time you pull out a pencil, pen, or open your laptop to a writing program. First thing’s first, you have to get your game out of your head. Write it down and put it somewhere you can reference it later.

2. Writer’s Block

So if you’ve opened a text editor or you have a pen in your hand you’ve successfully completed step one. Now, what do you write? I like to start with the five W’s:

Whom?

  • Does your game appeal to a specific age range or interest group or gender or even ethnic background?
  • Will you have a large audience your game will appeal to or a small audience?
  • What are the benefits and downsides of the audience you’ve identified?

What?

  • What kind of game are you trying to make?
  • What programming language best suits this kind of game?
  • Does it fit into a specific genre of game or does it span multiple genres?
  • Does it embody a completely new genre?
  • Can you find other games that are similar to the game you are trying to make? If so, what do these games do well and where do fall short?
  • Are there lots of other games on the market similar to the type of game you’re trying to make?
  • What will your charge for your game?
  • What do other, similar games of this type charge?
  • What are the benefits and downsides of the type of game you’re trying to make?

Where?

  • Where does your game take place?
  • What kind of maps or features or environment are unique to your game?
  • What are the benefits and downsides of where your game takes place?

When?

  • When will you have time to work on this game?
  • When can you start this game?
  • When can you fund the development of this game?
  • What are the benefits and downsides of developing this game?

Why?

  • Why are you making this game?
  • Why is your game unique?
  • Why will your game stand out from the crowd?
  • Why will people choose to play your game over other similar games?
  • Why will people pay for your game?
  • What are the benefits and downsides of making this game?

3. Make A Design Document

Your design document is a refined version of everything you’ve written down in step 2. Go back and really analyze what your goals for the game are and if what you’ve written down makes sense in the larger picture. Sometimes a good idea you have for one area of the game will conflict or make another part of the game tedious, uninspired or downright frustrating. For a game design document I like to use the following format:

  1. Intro
    • What is the vision for your game and a short description of how the game is played
  2. Audience, Platform & Marketing Strategies
    • Who the game is for, what platforms you’re making it for and what sets your game apart that will make it marketable and different from others
  3. Core Gameplay & Mechanics
    • How the game is played including physics, rules and limitations
  4. Characters
    • What characters are in your game including what they look like, their names and backgrounds and personalities
  5. Story, Themes & Twists
    • If your game has an overarching story then you’ll outline your plot and how the game progresses with the story line
  6. World
    • Describe the world your game is set in, including maps and locations and their purpose or importance
  7. Assets
    • All the different images, music, animations, etc that you will need to have a fully functional game
  8. Technical Specs
    • What language you’re using, how games are loaded/saved, where games are stored, the number of servers you’ll need and anything else relating to the technical setup of your game
  9. Interface
    • What the game interface looks like and how the player will interact with it
  10. Outside References
    • Articles, links, design inspriations, or anything else that you’re using as a reference for the game you’re making
  11. Appendix
    • Code style guidelines, dictionary of terms, and anything else that is important for understanding your design document that may not necessarily relate to your game directly

Once you’ve fully fleshed out your game design by going into depth about the features, physics, economy, weapons, characters and how the game works it’s time to break it down. Start by creating lots of of small, easy tasks you can accomplish in order to see your core game mechanics to completion enough that you could play a simple version of your game without any extra bells and whistles. Set yourself up to do as little as you have to but as much as you need to in order to get a really simplified, yet completed, version of your game.

JS Tutorial: Recursive Promise Calls

Leave a comment Standard

The Reason

So in trying to help a co-worker I was looking for an example of how you can do recursive promise calls. To my surprise I didn’t find any soooo now you get this post🙂 In a typical scenario you would chain your promises one after the other, however in real world situations the solution is not always so cut and paste. For instance you may need to ping a crappy device and wait for the results of the first ping to come back before you can ping the device again. If that’s the case upgrade your device, but if that’s not an option then you can always use this slash and hack solution of recursive promise calls which I would not recommend unless you have to but yeah, real life sucks sometimes. So here you have it, I hope this helps.

Test or fork the working example on Plunker

The Code

//somewhere to store the results of your recursive calls
var results = [];

/**
* Recursive function
*
* @param int val how many times to call this function recursively
* @return null
**/
var promiseMore = function(val) {
  console.log('attempting promise ' + val);

  //defer the promise
  var deferred = Promise.defer();

  //check your recursive conditions, keep looping while true
  if (val > 0) {
    //run your ajax request
    $.ajax({
      method: 'post',
      url: 'https://api.random.org/json-rpc/1/invoke',
      data: JSON.stringify({
        "jsonrpc": "2.0",
        "method": "generateSignedStrings",
        "params": {
          "apiKey": "4e69c4a7-4e47-4811-b110-6c7bfce079db",
          "n": 1,
          "length": 4,
          "characters": "abcdefghijklmnopqrstuvwxyz",
          "replacement": true
        },
        "id": 29970
      }),
      dataType: 'json',
      success: function(response) {
        document.write('Got data for promise ' + val + '<br/>');
        results.push(response.result.random.data[0]);

        //this triggers the recursion
        d = promiseMore(--val);

        //resolve this promise
        return deferred.resolve(d);
      }
    });
  } else {
    doSomethingWithResults();
  }
}

/**
* Whatever you want to do when your recursive promises are done firing
*
* @return null
* @print lots of BS random string results from our promises
**/
var doSomethingWithResults = function() {

  document.write('<br/>============<br/>');
  document.write('Doing something with the results now...');
  document.write('<br/>============<br/><br/>');

  //print out the data we got from the recursive promises
  for (i = 1; i <= results.length; i++) {
    document.write('Results ' + i + ': ' + results[i-1] + '<br/>');
  }
}

//kick off the call to the recrusive promises
promiseMore(10);

 

Html5 Game Tutorial: Pong

Comments 2 Standard
Screen Shot 2016-02-07 at 7.25.28 PM

This is a simple HTML5 version of the classic game of pong. Play against the computer for as many levels as you can. The computer gets faster and more competitive the higher the level gets. The game can easily be customized to grow/shrink the paddles and the computer’s difficulty if you’re looking for a challenge after you’ve finished putting the tutorial together. You’ll need a current version of a browser (Chrome, Firefox) that supports HTML5 in order to complete this tutorial. Enjoy!

Download the Code or Fork on Plunker or Try the Working Version

Create the HTML File

The beauty of html5 is that you can program it using javascript. This makes your html file small and super simple. All we need to do is create a canvas for the game and then include the javascript file:

<html>
<canvas id="battlePong"></canvas>
< script type="text/javascript" src="battlePong.js"></script>
</html>

Create the Javascript File

/**
* File: BattlePong.js
* Purpose: HTML5 pong game
* Author: Design1Online.com, LLC <jade@design1online.com>
* Created: 6/7/2016
**/

//global game variables
var game = {
 debug: true,
 canvas: null,
 canvasContext: null,
 frameRate: 1000,
 framesPerSecond: 30,
 fonts: {
 header: '30px Arial',
 regular: '15px Arial'
 },
 colors: {
 net: 'gray',
 background: 'black',
 header: 'red',
 text: 'white'
 },
 screens: {
 winner: false,
 startGame: true,
 levelUp: false,
 continue: false
 },
 ball: {
 x: 50,
 y: 50,
 speedX: 10,
 speedY: 4,
 threshold: 35,
 radius: 10,
 color: 'blue'
 },
 level: 1,
 pointsPerLevel: 3,
 player: {
 score: 0,
 lives: 5,
 paddle: {
 y: 250,
 thickness: 10,
 height: 100,
 color: 'green'
 }
 },
 computer: {
 score: 0,
 paddle: {
 y: 250,
 thickness: 10,
 height: 100,
 speed: 6,
 color: 'red'
 }
 }
};

/**
* Start the game when the window loads
**/
window.onload = function() {

 //init the canvas
 game.canvas = document.getElementById('battlePong');

 //adjust canvas to window size
 game.canvas.width = window.innerWidth - game.computer.paddle.thickness;
 game.canvas.height = window.innerHeight;

 //create the context
 game.canvasContext = game.canvas.getContext('2d');

 //add event listeners
 game.canvas.addEventListener('mousedown', mouseClickHandler);
 game.canvas.addEventListener('mousemove', mouseMoveHandler);

 //start buffering the screen
 setInterval(function() { buffer(); }, game.frameRate / game.framesPerSecond);
};

/**
* Figure out the player's mouse position
**/
function mouseMoveHandler(e) {
 var mousePos = mousePosition(e);
 game.player.paddle.y = mousePos.y - (game.player.paddle.height / 2);
}

/**
* Return the x,y coordinates of the mouse in
* relation to the screen
**/
function mousePosition(e) {
 var rect = game.canvas.getBoundingClientRect();
 var root = document.documentElement;

 return {
 x: e.clientX - rect.left - root.scrollLeft,
 y: e.clientY - rect.top - root.scrollTop
 };
}

/**
* Handle mouse clicks
**/
function mouseClickHandler(e) {

 if (game.debug) {
 console.log('mouseClickHandler()');
 }

 if (game.screens.startGame) {

 if (game.debug) {
 console.log('Removing start screen');
 }

 game.screens.startGame = false;
 }
 else if (game.screens.continue) {

 if (game.debug) {
 console.log('Removing start screen');
 }

 game.screens.continue = false;
 }
 else if (game.screens.levelUp) {

 if (game.debug) {
 console.log('Removing level up screen');
 }

 game.screens.levelUp = false;
 }
 else if (game.screens.winner) {

 resetGame();

 if (game.debug) {
 console.log('Removing winner screen, showing start screen');
 }

 game.player.score = 0;
 game.computer.score = 0;
 game.screens.winner = false;
 game.screens.startGame = true;
 }
}

/**
* Start the game
**/
function startGame() {

 if (game.debug) {
 console.log('Starting game...');
 }

 if (game.player.lives <= 0) {
 game.screens.winner = true;
 }

 game.ball.speedX = -game.ball.speedX;
 game.ball.x = game.canvas.width / 2;
 game.ball.y = game.canvas.height / 2;
}

/**
* Move the ball and the computer mouse paddle
**/
function move() {

 var deltaY = 0;

 //move computer paddle
 var center = game.computer.paddle.y + (game.computer.paddle.height / 2);

 if (center < game.ball.y - game.ball.threshold) {
 game.computer.paddle.y = game.computer.paddle.y + game.computer.paddle.speed;
 } else if (center > game.ball.y + game.ball.threshold) {
 game.computer.paddle.y = game.computer.paddle.y - game.computer.paddle.speed;
 }

 //move ball
 game.ball.x = game.ball.x + game.ball.speedX;
 game.ball.y = game.ball.y + game.ball.speedY;

 //check for paddle collisions
 hitCollision();

 if (game.ball.y < 0) {
 if (game.debug) {
 console.log('Inverting ball Y speed 1');
 }

 game.ball.speedY = -game.ball.speedY;
 }
 if (game.ball.y > game.canvas.height) {

 if (game.debug) {
 console.log('Inverting ball Y speed 2');
 }

 game.ball.speedY = -game.ball.speedY;
 }
}

/**
* Check for ball/paddle collisions
**/
function hitCollision()
{
 //player paddle check
 if (game.ball.x <= 0) {

 if (game.debug) {
 console.log('player paddle collision check');
 console.log('ball', game.ball);
 console.log('player paddle', game.player.paddle);
 console.log(
 'hit or miss',
 game.ball.y > game.player.paddle.y,
 game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
 );
 }

 if (game.ball.y > (game.player.paddle.y) &&
 game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
 ) {
 game.ball.speedX = -game.ball.speedX;

 deltaY = game.ball.y - (game.player.paddle.y + game.player.paddle.height / 2);
 game.ball.speedY = deltaY * 0.35;
 } else {
 game.computer.score++;
 game.player.lives--;
 game.screens.continue = true;
 startGame();
 }
 }

 //computer paddle check
 if (game.ball.x >= game.canvas.width) {

 if (game.debug) {
 console.log('player paddle collision check');
 console.log('ball', game.ball);
 console.log('player paddle', game.computer.paddle);
 console.log(
 'hit or miss',
 game.ball.y > game.computer.paddle.y,
 game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.height)
 );
 }

 if (game.ball.y > (game.computer.paddle.y) &&
 game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.radius)
 ) {
 game.ball.speedX = -game.ball.speedX;

 deltaY = game.ball.y - (game.computer.paddle.y + game.computer.paddle.height / 2);
 game.ball.speedY = deltaY * 0.35;
 } else {
 game.player.score++; //increase score

 //level up
 if (game.player.score > 0 && game.player.score % game.pointsPerLevel === 0) {
 game.player.lives++; //get another life
 game.level++; //level up
 game.computer.paddle.speed += 1.3; //increase computer paddle speed
 game.screens.levelUp = true;
 } else {
 game.screens.continue = true;
 }

 startGame();
 }
 }
}

/**
* Draw the game board
**/
function drawBoard() {

 //draw the net
 for (var i = 0; i < game.canvas.height; i += 10) {
 drawRectangle(game.canvas.width / 2 - 1, i, 2, 1, game.colors.net);
 }

 //draw the score text
 var offset = 100;

 //set the header text
 var header = "BattlePong!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 game.canvasContext.fillText(header, offset, 30);

 //set the colors and font style
 game.canvasContext.fillStyle = game.colors.net;
 game.canvasContext.font = game.fonts.regular;

 //set the score text
 var score = "Score: " + game.player.score;
 game.canvasContext.font = game.fonts.text;
 var scoreSize = game.canvasContext.measureText(score);
 game.canvasContext.fillText(score, offset + 5, 50);

 //set the lives text
 var lives = "Lives: " + game.player.lives;
 var livesSize = game.canvasContext.measureText(lives);
 game.canvasContext.fillText(lives, offset + scoreSize.width + 25, 50);

 //set the copyright text
 var copyright = "Games by design1online.com, LLC";
 var copyrightSize = game.canvasContext.measureText(copyright);
 game.canvasContext.fillText(copyright, game.canvas.width - copyrightSize.width - offset/4, game.canvas.height - offset/4);

 //player paddle
 drawRectangle(
 0,
 game.player.paddle.y,
 game.player.paddle.thickness,
 game.player.paddle.height,
 game.player.paddle.color
 );

 //computer paddle
 drawRectangle(
 game.canvas.width - game.computer.paddle.thickness,
 game.computer.paddle.y,
 game.computer.paddle.thickness,
 game.computer.paddle.height,
 game.computer.paddle.color
 );

 //ball
 drawBall(game.ball.x, game.ball.y, game.ball.radius, game.ball.color);
}

/**
* Draw the ball
**/
function drawBall(centerX, centerY, radius, color) {
 game.canvasContext.fillStyle = color;
 game.canvasContext.beginPath();
 game.canvasContext.arc(centerX, centerY, radius, 0, Math.PI * 2, true);
 game.canvasContext.fill();
}

/**
* Draw paddle
**/
function drawRectangle(leftX, topY, width, height, color) {
 game.canvasContext.fillStyle = color;
 game.canvasContext.fillRect(leftX, topY, width, height);
}

/**
* Reset for a new game
**/
function resetGame()
{

 if (game.debug) {
 console.log('Resetting game...');
 }

 game.level = 1;
 game.computer.paddle.speed = 6;
 game.player.score = 0;
 game.computer.score = 0;
 game.player.lives = 5;
}

/**
* Draw the winner screen
**/
function screenWinner() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;
 var header = "Game Over!";
 var score = "Score: " + game.player.score;

 //set the header text
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the score text
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var scoreSize = game.canvasContext.measureText(score);
 game.canvasContext.fillText(score, center - scoreSize.width/2, height + 25);
}

/**
* Draw the continue screen
**/
function screenContinue() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set the header text
 var header = "Missed Ball!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the info text
 var info = "Click anywhere to start the next ball";
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Draw the level up screen
**/
function screenLevelUp() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set header
 var header = "Level " + game.level;
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the regular text color and font
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;

 //set the level text
 var info = "Click anywhere to start the next ball";
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Draw the start screen
**/
function screenStartGame() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set the header text
 var header = "BattlePong!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the info text
 var info = "Click anywhere to start playing";
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Buffer the screen
**/
function buffer() {

 //black out the screen
 drawRectangle(0, 0, game.canvas.width, game.canvas.height, game.colors.background);

 //draw one if the screens if they're active
 if (game.screens.winner) {
 screenWinner();
 return;
 }
 else if (game.screens.continue) {
 screenContinue();
 return;
 }
 else if (game.screens.levelUp) {
 screenLevelUp();
 return;
 }
 else if (game.screens.startGame) {
 screenStartGame();
 return;
 }

 //playing the game
 move();
 drawBoard();
}

Test Your File

Open your html file in a browser. Make sure that your javascript file is located in the same place. Voila! Now you can tweak and refine it to your hearts content.

HTML5: Analyze or generate your favicon

Leave a comment Standard

RealFaviconGenerator.net analizes your favicon and tells if it is compatible with major platforms. You can also use it to create a favicon if you don’t have one already. It’s a pretty nifty tool. Check it out at RealFaviconGenerator.net

Scrum Mastering

Leave a comment Standard

Note: this is not a comprehensive post, just stuff I picked up during my recent scrum master certification class. Take from it what you will🙂

What Is It?

Daily standup meeting, maximum of 15 minutes. 7 people per scrum team is the best setup, 10 is iffy. Open space is best for scrum because it keeps people alert and standing means they’ll be paying more attention. Best to do the standup meeting in an empty room.

Product Backlog

Composed of user personas (ie who will use your software, what kind of person are they) ordered from highest importance to lower importance based on who is the largest user base, how much $$ they have, how frequently do they will use it, what kind of social impact do they have, features specific to them and features shared. This is used to help the product owner determine the business value and priority of each user story. These are then taken to the release backlog. This is who the product is for. In the picture below, features are placed horizontally for the user persona they apply to and turned sideways to indicate they are core functionality. These features are turned into user stories. Typically agile teams will tackle core functionality first since it spans multiple user stories.

product_backlog

Sprint Task Board

Kanban board (Japanese work meaning status, graphic). Has three columns, TODO, IN PROGRESS and DONE. TODO section contains the tasks to be completed also known as Sprint Backlog.

User stories are high level concepts that are broken into tasks which can be completed. User stories should be completed in a single sprint.

Tasks are estimated according to time.

User stories are assigned story points according to complexity of the story.

When you’re planning a story/tasks you plan to keep them busy for 70% of their time since the other 30% might be discovering things that you’ve missed.

Decomposing user stories into tasks is done in the sprint planning meeting.

QA testing should be done once the story is done rather than each individual task.

If you have a separate QA team then you need a QA task for each user story. The QA team would estimate the value.

sprint_taskboard

Sprint Burndown Chart

A chart of the progress done over time. It starts with the total number of estimated minutes and drops as time passes.

A typical sprint has little work and then the work is added and then it falls over time. If that’s happening then you’re not planning your sprints properly and you’re not protecting the sprint (ie adding more work) when you should be. In this case you can see the team has a clear planning issue, therefore the curve of the sprint burndown will be more of an downward trend.

When you start achieving complete sprint burndown you might not even need to use this chart anymore. It’s like training wheels on a bike, once you’ve figured it out you won’t need it anymore.

Release Burndown Chart

This is a similar concept to the sprint burndown except it’s used with sprints instead of with sprint tasks. By calculating the velocity you can add and remove user stories from the release planning in order to get all the story points done in the year.

Definition of Done

The processes that need to be completed for each User Story are put up on a checklist and then each part is checked off as it’s completed. Once all checkboxes are marked the User Story is considered done.

definition_done

Sprint Backlog & User Capacity Chart

Setup a user capacity rundown chart to help organize the team and figure out how much capacity you have for the sprint. The picture below shows the sprint taskboard and the sprint backlog. The white piece of paper is the user capacity chart. User capacity starts with 80 hours for the 2 weeks and then goes down if team members will be out/vacation. Then you add some buffer for other stuff they might end up working on or tasks taking longer than expected. Next you start asking who wants to take which tasks and use up the remaining capacity. This will also help you figure out if you can take on more work or have too much work for the sprint. This is how the team plans to accomplish the sprint goals.

sprint_backlog

Team Calendar

Recommended team calendar setup. Backlog grooming will help you start to plan your user stories for the next sprint. DSM = daily standup meeting.

team_calendar

The Agile Manifesto

Winston Royce invented the waterfall model by documenting what his team was doing during their development process. The core values of the Agile Manifesto are:

Individuals and Interactions – over processes and tools
Working and Software – over comprehensive documentation
Customer Collaboration – over contract negotiation
Responding to Change – over following a plan

The principles behind agile are:

  1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software
  2. Welcome changing requirements, even late in development. Agile process harnesses changes for the customer’s competitive advantage.
  3. Deliver working software frequently. from a couple of weeks to a couple of months, with a preference to the shorter timescale
  4. Business people and developers must work together daily throughout the project
  5. Build projects around motivated individuals. Give them the environment and support they need, and thrust them to get the job done.
  6. The most efficient and effective method of conveying info to and within a dev team is face to face conversation.
  7. Working software is the primary measure of progress.
  8. Agile processes promote sustainable development. The sponsors, developers and users should be able to maintain a constant pace indefinitely
  9. Continuous attention to technical excellence and good design enhances agility.
  10. Simplicity — the art of maximizing the amount of work not done — is essential.
  11. The best architectures, requirements and designs emerge from self-organizing teams.
  12. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts behavior accordingly

Empirical vs Defined

Defined is something that has architecture and structure, ie a sewing pattern. Empirical is something that isn’t well defined, ie a custom made garment made without a sewing pattern. Software is inherently empirical. The first time you make a feature that you’ve never attempted before you won’t know how long it’s going to take and how much effort it requires therefore you can only provide an estimate. Something that is well defined has been done before therefore you can give a set amount of time and effort to complete the task.

Output vs Outcome

We often focus so much on the output that we forget about the outcome. Producing more code/features doesn’t necessarily mean you’ll have a better outcome. In terms of Agile and Scrum outcome is more important than output.

Product Owners

Agile Is Just That

Since Agile is a set of principals there’s many different ways you can accomplish it. Here’s a look at the Spotify engineering culture which has been using Agile from the beginning. You can quickly see how they’ve deviated from what most people consider the “traditional” ideas.

Scrum Developers

6 people per team, 1 of them is scrum master, is a good idea because it allows them to pair up for pair programming.

Motivating Your Team

Autonomy and mastery and contributing are better motivators than money or bonuses or prizes.

Golden Circle

A. Why you want to create the product (should invoke a vision/feeling)

B. How you’re going to create the product

C. What you’re going to do to create the product backlog

Useful Team Activities

2-Dimensional Axis Chart

X axis is used to denote how much something was successful or unsuccessful (loved it vs hated it). Y axis is used for time. Sticky notes are then added to correspond with the features/activities that occurred. This lets people vote someone anonymously and gives you a feel of what you could work on improving.

Planning Poker

Create cards (100, 60, 20, 8, 1) that represent the story points which are tied to the complexity, effort and cost to create the feature. Assign those values to the user stories via vote (majority wins, hear from outliers and re-vote after). Adding all of those up will give you the total user story points for that release.

Dot Chart

Take the items you can improve from the previous chart and put them on a new graph. Now have people come up and put a dot next to those they feel most passionately about, a larger dot indicates they feel more strongly about it. This will help you identify the areas where the majority agrees there is room for improvement. Sorry it’s blurry.

dot_chart

After a Team commits to sprint goals what authority do they have?

The team does whatever is necessary to achieve the goal.

How are development teams guided during a sprint?

By their collective knowledge and experience.

From Product Vision to Your First Sprint

  1. Create the product backlog from the golden circle design
  2. Create the user personas
  3. Create the user stories (product backlog)
  4. Move the stories into the release backlog
  5. Move the stories into the different sprints
  6. Create tickets for the sprints
  7. Move the user stories from the release backlog into the sprint task board when your release backlog is done being planned.
  8. Now create 7-10 tasks for the user story
  9. Discover any dependencies between the tasks
  10. Now we have to estimate how long it takes to complete the task using 8, 4, 2 and 1 hours (finger voting). Any task that everyone votes for an 8 is too complex and needs to be split into additional tasks. User stories should be completed in under a week, if your user stories are indicating more than 40 hours then you need to split them up.
  11. Once you have the sprints planned it’s time for capacity analysis.
    1. For someone with an 80 hour sprint you should expect that they only have 55 hours of actual work time — this accounts for buffer time.

 

 

 

 

Protect Apache web-server from application DoS attacks (Ubuntu)

Leave a comment Standard

Good stuff.

0xicf

This tutorial assumes that you have a running Ubuntu Server, that networking has been set up, and that you have ssh access.

Apache2 is the default web-server used by many Linux installations. It is not the only one available, or the best for all circumstances, but it covers many usage scenarios. During the installation, you may be asked which web-server to reconfigure automatically. Answer ‘apache2’.

Install Apache2

Use the following command to install Apache2 and other libraries.

$ sudo apt-get -y install apt-get install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apache2-utils libexpat1 ssl-cert libapache2-mod-php5 php5 php5-common php5-gd php5-cli php5-cgi libapache2-mod-fcgid apache2-suexec php-pear php-auth php5-mcrypt mcrypt libapache2-mod-suphp libopenssl-ruby libapache2-mod-ruby

Update Timezone and Check Correct Time

To reduce confusion with shared or mirrored data, all servers ought to run as close to as in-sync as possible. Some cryptographic key management systems require accurate time. Lastly, for corporate servers, Sarbanes-Oxley and HIPAA Security Rules require…

View original post 559 more words

PHP Tutorial: Cookies vs Sessions

Leave a comment Standard
1421823729zxptl

If you’re interested in making any kind of web based application then learning how to use sessions and cookies is a must. Many people don’t understand how these work and how they different from each other, and why you would choose to use one versus the other. So put on your thinking caps and let’s get started.

What is a Cookie?

A cookie is a data file that’s written to your browser’s localStorage with data you want to keep track of for a user. So what’s localStorage? The best real world analogy I can give you is to think about it like a 3 ring binder that you can add, update and remove files from. In this example a cookie would be a piece of paper in your 3 ring binder.

How Do Cookies Work?

When you navigate around the Internet your browser is constantly sending and receiving information from the websites you want to access. These are called HTTP headers. HTTP headers contain important information about the requests and responses being sent back and forth from a browser to a server. When someone has an active cookie from your website in their browser’s localStorage it automatically passed in the HTTP headers to the site of origin in the $_COOKIE variable of PHP. Since headers have to be sent before any output setting a cookie must always go at the top of your file.

How do I Create a Cookie?

<?php
$name = "myCookie";
$value = "hello world!";
$expires = time() + 60 * 60 * 24; //1 day
$path = "/";
$domain = "yourwebsite.com";
$secure = 0; //0 for false, 1 for true
$httponly = 0; //0 for false, 1 for true

//let's tell the browser to create our cookie
setcookie($name, $value, $expires, $path, $domain, $secure, $httponly);

//let's make a cookie array too
setcookie("cookieArray[0]", "A");
setcookie("cookieArray[1]", "B");
setcookie("cookieArray[2]", "C");

//you must refresh the page before your new cookies are visible
echo "refresh the page to see your cookies: " . $_COOKIE['myCookie'];

//this will loop through and display your array cookies
foreach ($_COOKIE['cookieArray'] as $key => $value)
{
 echo "<br/>array cookie $key => $value";
}
?>

In this first example we’ve created a cookie called myCookie that stores the value of hello world! In order to see something printed on the screen you must refresh the page. This is because the HTTP headers must be sent from the server to your browser and then from your browser back to the server before they show up in the $_COOKIE variable.

Expires is an optional value that tells the browser how long to keep our cookie before it deletes it. By using the current time() and then adding on an extra 24 hours our cookie will only stick around for a day before the browser deletes it. So in this example if your cookie is created at today at 12noon EST it will expire tomorrow at 12noon EST. When your cookie is expired you’ll have to create a new one if you want to store your $value again.

Next we’ve set a path for our cookie. This is also an optional field and will default to / if you don’t give it a value. This tells the browser where this cookie will be available. So let’s say your website is http://yourwebsite.com and you only want this cookie to be available when you’re inside the http://yourwebsite.com/users/ section or your website. If that were the case we’d change the path to /users/ and then our cookie will only be accessible when we’re in the users directory. When we leave the path at / it means our cookie is available on any part of the domain we’ve given it.

The domain of your cookie is optional. If you don’t provide a domain for your cookie it may default to your current domain name. You can also set your domain name to a subdomain. So for instance, if we had a subdomain of http://users.yourwebsite.com we would set our domain to users.yourwebsite.com then our cookie would only be available when we’re inside our users subdomain.

The secure section of the cookie is optional and should only be set to true if you’re using https.

The httponly is optional and tells newer browser to only make your cookie accessible in the HTTP header. Not all browsers support this functionality, however it has been added to help prevent against cross site scripting (XSS) attacks.

How do I Access Cookie Values?

<?php
//this shows you a single cookie
echo $_COOKIE['myCookie'];

//this shows you all available cookies
print_r($_COOKIE);
?>

Once you have a cookie set you can access it by using the $_COOKIE variable in PHP and then pass it the name of the cookie you want to access or you can use a print_r() call to print all available cookies.

How do I Delete a Cookie?

<?php
//unset the single cookie
unset($_COOKIE['myCookie']);

//unset the array cookies
unset($_COOKIE['cookieArray']);

//update the cookie's expiration date to sometime in the past
setcookie("myCookie", false, time()-1);
setcookie("cookieArray[0]", false, time()-1);
setcookie("cookieArray[1]", false, time()-1);
setcookie("cookieArray[2]", false, time()-1);
?>

Sometimes you want to remove a cookie. There are two different ways to do this. The first is to unset() the cookie and the second is to update the expiration date to a time in the past which will force your browser to remove it. Just like when we set a cookie, you must refresh the page before you will see that your cookie has been removed.

How do I Edit a Cookie?

<?php
//to edit a single cookie value
setcookie("myCookie", "My new value");

//to edit a cookie array
setcookie("cookieArray[0]", "one");
setcookie("cookieArray[1]", "two");
setcookie("cookieArray[2]", "three");
?>

As long as the cookie exists all you need to do is set the cookie with the same name and give it a different value. You won’t see that the values in your cookie have changed until you refresh the page since cookies are sent in an HTTP header.

Cookie Trouble Shooting

  • If you’re having trouble setting a cookie and you’re getting a headers already sent error then you have some kind of output (text, spaces, html, images, etc) that are being displayed to the screen before you’re calling your setcookie() function.
  • Once you’ve added, edited or deleted a cookie you must refresh the page before you can see that your changes have taken place. This is because cookies are sent in HTTP headers.
  • Cookies must be deleted with the exact same parameters as they were set with.
  • Cookie arrays are stored as one file for each index in the array. For this reason large arrays are not recommended. If you need to store lots of data in a cookie it’s more useful to use a single cooke and concatenate the values with implode() then retrieve the data  using explode().
  • If one of the values in your cookie resolves to a false your cookie will be deleted. For this reason you shouldn’t use true/false booleans but instead use 0 and 1.
  • It is not recommended to serialize your cookie values as this can cause security holes.
  • If the user’s browser has cookies disabled or will not allow cookies to be stored then you won’t be able to create a cookie in their localStorage. This problem gave rise to the creation of sessions.

What Is a Session?

Sessions are the best solution for short term storage of data and dealing with user’s browsers that don’t allow the creation of cookies. Sessions will attempt to create a cookie and if the attempt fails will instead propagate via the URL. However a session will only persist over the duration of a user’s visit on your website. Once the user leaves your site the cookie (if one was created) is deleted so there is no persistent information retained about the user in the browser’s localStorage once they’ve left your website.

How do I Create a Session?

<?php
//you have to start the sessions before you can use them
session_start();

//set a single session value
$_SESSION['mySession'] = "hello world!";

//set an array in a session
$_SESSION['myArray'] = new array('A', 'B', 'C');

//set an object in a session
$_SESSION['myObject'] = new myObject();
//this tells php your done making changes to the session
session_write_close();

//session values are immediately available
echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

All sessions must be started with the session_start() call unless you have them set to auto start in your php.ini file. Usually this isn’t the case with most hosting providers. In addition session_start can take parameters to configure the length of the session and the storage location, etc, however most hosting providers don’t let you change these settings so I won’t cover them here.

Sessions are sent via HTTP headers just like cookies are (when PHP tries to create a temporary cookie), however since they can persist without cookies the data is immediately accessible once it has been initialized. This means you won’t have to refresh the page to access the data you’ve stored in them.

How do I Access Session Values?

<?php
session_start();

echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

Unlike cookies where you have to refresh the page before you can access them, session values are immediately available once they’ve been set. All you have to do is start the sessions (unless sessions have been set to auto start) and then look for the name of the session you want to access.

How do I Delete a Session?

<?php
session_start();

//remove a single session values
unset($_SESSION['mySession']);
unset($_SESSION['myArray']);
unset($_SESSION['myObject']);

//alternative way to remove a session values
$_SESSION['mySession'] = false;
$_SESSION['myArray'] = null;
$_SESSION['myObject'] = '';
//this tells php your done making changes to the session
session_write_close();

//remove all session values
session_destroy();
?>

The best way to remove a session is to unset it, however you can also set the value to falsey or call session_destroy() to remove all session values.

How do I Edit Session Values?

<?php
//you have to start the sessions before you can use them
session_start();

//edit a single session value
$_SESSION['mySession'] = "new value!";

//edit an array in a session
$_SESSION['myArray'] = new array('one', 'two', 'three');

//edit an object in a session
$_SESSION['myObject'] = new myNewObject();

//this tells php your done making changes to the session
session_write_close();

//session value changes are immediately available
echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

You can edit session values the same way you set them initially.

Session Troubleshooting

  • If you’re having trouble getting a session started and you’re getting  headers already sent errors then you have some kind of output (text, spaces, html, images, etc) that are being displayed to the screen before you’re calling your start_session() function.
  • Sessions will only last for the duration of a user’s visit or for the session_expiration time that’s set in the php.ini file. You can learn more about session configuration values in the PHP manual.
  • Make sure you’re not doing an unset($_SESSION) as this will make it impossible to register any new values in the $_SESSION.
  •  You can’t use reference variables in sessions.
  • If register_globals are enabled they will overwrite variables with the same $_SESSION name. For instance if you have a session named mySession and register_globals is enabled and you create a $mySession variable it will overwrite the $_SESSION[‘mySession’] value with whatever you’ve assigned to $mySession.
  • If you’re having a problem changing values in your session make sure you’re calling session_write_close() after you’ve made changes to session values. This is especially important if you’re doing a lot of asynchronous ajax calls.

Should I Use a Session or a Cookie?

The best way to answer this question is do you need data on a user to persist once they’ve closed their browser? Sessions will only last for the duration of a user’s visit on your website, they will disappear as soon as the user has closed all windows and tabs that they have open for your website. Cookies, on the other hand, will remain on a user’s computer until the user removes them from their browser or they expire.

Pros & Cons of Sessions vs Cookies

Type Pros Cons
Sessions Excellent for short term data storage

Can access immediately after initialization

Will create a temporary cookie if cookies are enabled/supported, otherwise propagated on the URL

Can be used for authentication

Only last for the duration of the user’s visit

Susceptible to XSS attacks

Cookies Excellent for long term storage of data

Can be used for authentication

Must be enabled/supported on the browser

Must refresh the page before you can access cookie data

Susceptible to XSS attacks