Skip to content

Commit

Permalink
Envoy 0.0.1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
Gareth Aye committed Mar 30, 2014
1 parent 8eeec9d commit fed7dc7
Show file tree
Hide file tree
Showing 60 changed files with 2,945 additions and 1 deletion.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.cover.js
*.js.txt
/coverage.zip

/app/.meteor/.gitignore
/app/.meteor/local
/app/packages/
/coverage
/coverage-browser
/coverage-integration
/node_modules
/packages
90 changes: 90 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module.exports = function(grunt) {
grunt.initConfig({
jshint: {
all: [
// We need to specify app/ subdirectories since we don't want to
// accidentily lint anything in app/.meteor/ or app/packages/
'Gruntfile.js',
'app/client/**/*.js',
'app/lib/**/*.js',
'app/private/**/*.js',
'app/server/**/*.js',
'tasks/**/*.js',
'test/**/*.js'
]
},

istanbul: {
// Server-side unit tests with mocha
mocha: {
paths: [
'test/unit/nodejs/**/*.js',
'test/unit/shared/**/*.js'
]
},

// Bring up express server with istanbul connect middleware
startServer: {},

// Download coverage data from istanbul express server
// and kill server.
stopServer: {},

// Instrument javascript
instrument: {
paths: [
'app/client/**/*.js',
'app/lib/**/*.js'
]
},

restore: {
paths: [
'app/client/**/*.js.txt',
'app/lib/**/*.js.txt'
]
}
},

// Client-side unit tests with mocha
mocha: {
test: {
src: ['test/index.html'],
options: {
reporter: 'Spec',
run: true
}
}
},

// Selenium webdriver tests
mochaTest: {
webdriver: {
options: {
reporter: 'spec',
require: 'test/setup.js',
timeout: '60s'
},
src: ['test/integration/**/*_test.js']
}
}
});

grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-mocha');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadTasks('./tasks');
grunt.task.registerTask('default', [
'jshint', // Lint
'istanbul:mocha', // Server-side unit test suite
// Instrument all the things and start the coverage server
// before we run unit and integration tests in the browser.
// We will post data to the coverage server from the browser.
'istanbul:instrument',
'istanbul:startServer',
'mocha', // Client-side unit test suite
'mochaTest', // WebDriverJs integration test suite
'istanbul:stopServer',
'istanbul:restore'
]);
};
94 changes: 93 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,96 @@
envoy
=====

Envoy is a multiplayer trading card game built with meteor.
[![Build Status](https://circleci.com/gh/gaye/envoy.png?circle-token=e2943dcf3107f6e6f6396a052f79c7c1aba87299)](https://circleci.com/gh/gaye/envoy?circle-token=e2943dcf3107f6e6f6396a052f79c7c1aba87299)

### Overview

Envoy is a multiplayer trading card game built with [meteor](https://meteor.com). It is intended to be (conceptually) similar to other trading card games like magic, yugioh and pokemon. Here are some of the project's high-level goals which (perhaps) differentiate it from other games.

1. Envoy is asynchronous by default. While your opponent is taking a turn, you can feed farm animals, build a pillow fort, etc.
2. Envoy is a modern, networked computer game. Most other, historic card games made design decisions that allowed humans to compute and store the game state. Nowadays, everyone and their mother has insanely powerful, general-purpose computers which opens up game options.
3. Envoy is an open platform. We will strive to make it so that other developers can build "apps" on top of our data ranging from alternate game players to marketplaces.
4. Many card games are optimized to make a lot of money off of folks with gambling problems. If Envoy ever has a commercial offering, we will make choices that align Envoy's profits with players' joy, well-being, and thought. Envoy's primary goal is to engage and entertain people in wonderful ways.

### The Game

+ Four kinds of cards: envoy, spell, device, and trap.
+ Envoys attack and defend.
+ Spells affect the game immediately when they are played.
+ Devices stay in play and have a continuous effect on the game.
+ Traps are played face down and the game engine triggers them when the game state meets certain conditions.
+ Players alternate taking turns.
+ A turn consists of
+ declaring defenders if the player is under attack,
+ resolving the combat,
+ "refreshing" envoys and devices,
+ drawing a card,
+ optionally casting one card to energy,
+ optionally playing any cards in hand and invoking "invokeable" abilities,
+ optionally attacking with any envoys in play that were played before this turn or have the "speedy" ability

### Directory Structure

```
app/ # <= where the main meteor app lives
app/.meteor/ # <= configure meteor version, packages
app/client/ # <= bundled into client
app/client/controllers/ # <= template data && controller code
app/client/style/ # <= css made available to clients
app/client/templates/ # <= handlebars templates
app/lib/ # <= shared between browser and server
app/lib/collections/ # <= meteor models
app/server/ # <= bundled into server
fixtures/ # <= json files that we mongoimport on start
tasks/ # <= custom grunt tasks
test/ # <= where tests live
test/integration/ # <= integration test cases
test/unit/ # <= unit test cases
test/unit/browser/ # <= unit tests for client-side code
test/unit/mocks/ # <= unit test mocks
test/unit/nodejs/ # <= unit tests for server-side code
test/unit/shared/ # <= unit tests for shared code
```

### Running Locally

To run envoy locally, you must first globally install:

+ firefox
+ java
+ meteor
+ mongodb
+ xvfb

Then...

```
// Install dependencies
npm install
cd app && ../node_modules/.bin/mrt install
// Run meteor
cd app && meteor
// In another terminal session, you can load some fixture data
./node_modules/.bin/grunt fixtures
```

### Tests

To run the lint and test suites:

```
// Install app, test dependencies
npm install
cd app && ../node_modules/.bin/mrt install
// Run lint, unit, and integration tests (in xvfb)
xvfb-run npm test
```
8 changes: 8 additions & 0 deletions app/.meteor/packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
accounts-facebook
accounts-password
accounts-ui
bootstrap-3
preserve-inputs
iron-router
standard-app-packages
underscore
1 change: 1 addition & 0 deletions app/.meteor/release
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.7.2
29 changes: 29 additions & 0 deletions app/client/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Meteor.subscribe('cards');
Meteor.subscribe('decks');

Router.configure({
layoutTemplate: 'layout'
});

Router.map(function() {
this.route('landing', { path: '/', template: 'landing' });

this.route('Decks#index', { path: '/decks', template: 'decks' });

this.route('Decks#new', {
path: '/decks/new',
template: 'deckbuilder',
before: function() {
Session.set('deck', { 'list': [], 'name': null });
}
});

this.route('Decks#show', {
path: '/decks/:name',
template: 'deckbuilder',
before: function() {
var deck = Decks.findOne({ name: this.params.name });
Session.set('deck', deck);
}
});
});
40 changes: 40 additions & 0 deletions app/client/controllers/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Template.card.formatCardtype = function(cardtype) {
if (!cardtype.secondary) {
return cardtype.primary;
}

return cardtype.primary + ' - ' + cardtype.secondary;
};

/**
* Takes a card's power and hp and returns a string like
* 3 / 3, ? / ?, ? / 5, etc.
* ? is a placeholder for a dynamic value that will,
* in the future, be given by the dependent game state.
*/
Template.card.formatCombat = function(power, hp) {
if (!_.isNumber(power)) {
power = '?';
}
if (!_.isNumber(hp)) {
hp = '?';
}

return power + ' / ' + hp;
};

Template.card.formatDescription = function(description) {
return description.join(' ');
};

Template.card.isZeroColor = function(cost) {
return !cost.color || cost.color === 0;
};

Template.card.isZeroColorless = function(cost) {
return !cost.colorless || cost.colorless === 0;
};

Template.card.isNotEnvoy = function(card) {
return card.cardtype.primary !== 'Envoy';
};
Loading

0 comments on commit fed7dc7

Please sign in to comment.