Skip to content

MrLeap/Statsi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Statsi automatically calculates various summary statistics for arbitrary, potentially deeply nested objects for you. As I've written games and simulations, I've wanted a data structure that would enable me to quickly prototype new features.

I wrote statsi to streamline this thought process:

Right now, each car as a constant speed.

var car = Statsi({speed: 100})
//car.status.speed = 100

I really want to adjust it based on every part on the car. I want to potentially modify it with effects I haven't even thought of yet.

Just sketch it as properties of your object and statsi will cope.

car.speed = 0; //Speed now comes from parts!
car.parts = {}; //slots for parts.

//Statsi ignores these names, but they give the data flavor.
car.parts.engine = {name: "fancy turbo engine", speed: 100}
car.parts.tires = {name: "sport tires", speed: 10}
car.parts.fuel = {name: "high_octane_fuel", speed: {$mul: 1.05}} //5% more speed, after all additions.
//car.status.speed is now 115.5.

What about a speed boost? Just add a key with the effect, delete it when it's done. Anything reading car.status.speed will get the updated value as it changes.

car.nos_active = {speed: {$mul: 2}} // weeee speed is 231 now.
setTimeout(() => {
	delete car.nos_active;
	//back to 115.
}, 5000)

Here's another example that shows how to use statsi to store character data for a contrived RPG.

let statsi = require('statsi');
let player = statsi({
	base_stats: {
		health: 100,
		strength: 5,
		intelligence: 5,
		agility: 5
	},
	gear: {
		right_hand: {name: "short sword", base_damage: 7},
		left_hand: {name: "buckler", block_chance: 0.3, defense: 3},
		chest: {name: "leather armor", defense: 10, health: 10}
	},
	buffs : [{name: "health buff", health: {$mul: 1.3}}],
	history : [{health: -10, name: "got attacked ouch!"}],
	attack: function(target) {
		var damage = (this.status.base_damage + this.status.strength);
		console.log("going to do this much damage: " + damage);
	}
});

This is the same kind of thing that's in example.js.

Lessons when you're designing: Does this effect get more severe every time it's applied? Put it in an array. Otherwise, object keys are often best since they're easy to overwrite and delete.

Examples

 > player.status
{ health: 133,
  strength: 5,
  intelligence: 5,
  agility: 5,
  base_damage: 7,
  block_chance: 0.3,
  defense: 13 }

If you run example.js, it'll launch a repl with a statsi object already instantiated. Try monkeying around with it!

Lets say you've got a statsi object like the above. You want to start letting big bad boss monsters debuff your player.

 > player.debuffs = [{health: {$mul: .5}}] //ouch, 50% health debuff :(
 > player.status
{ health: 66.5,
  strength: 5,
  intelligence: 5,
  agility: 5,
  base_damage: 7,
  block_chance: 0.3,
  defense: 13 }

A cleanse spell might be as simple as player.debuffs = [].

A dispell spell might be as simple as player.buffs = [].

An antidote might look like this player.debuffs = player.debuffs.filter((d) => {return d.name != 'poison'})

Hopefully this is giving you ideas.

Since adding up the durations of all your debuffs isn't a useful statistic, It's a good idea to start the names of things like that an underscore. _duration and the like will be ignored when .status is calculated.

Options

Here's a list of options you might want to customize, pass them as the second argument of your Statsi objects.

aggregateFunctionName the function to get your stats. Defaults to status.

operations If $mul isn't enough for you, you can add more operations here.

hide A function that accepts a key and a value from your statsi objects. Defaults to this:

function (k, v){
		return (k[0] === "_" || typeof v === "string" || typeof v === "function");
}```

This is used so statsi doesn't concatonate all your names together or other such weirdness. Override it if you need more / less things ignored.


## Installation

This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/).

Before installing, [download and install Node.js](https://nodejs.org/en/download/).
Node.js 0.10 or higher is required.

Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):

```bash
$ npm install statsi

TODO

-  Ergonomic constraints, triggers and lenses for your statsi objects.
-  Have greater control over the order stats are calculated for non assoiative operations.
-  Better performance characteristics. Storing your whole activity history for 100 entities in statsi gets unwieldy, but it shouldn't have to be.

About

A proxy that watches your collections and makes.. note of them..

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors