Giter Site home page Giter Site logo

seanohue / fantasy-time-crunch Goto Github PK

View Code? Open in Web Editor NEW
8.0 2.0 6.0 289 KB

A way of handling time and time-related state changes in a highly customizable way, for use with games and virtual worlds

JavaScript 99.77% Shell 0.23%
time fantasy games mud-engine mmo-engine utility-library ranvier hacktoberfest

fantasy-time-crunch's Introduction

fantasy-time-crunch

I needed a way of handling a made-up time system in a game, so I made this.

Sample Configuration

const time = {
  // One and only one unit is the smallest measured subdivision of time, defined as a 'tick'
  second: {
    tick: true,
    makes: {minute: 60},
  },

  // Larger units are defined by how many of a smaller unit they are subdivided into
  minute: {
    makes: {hour: 60},
  },

  // Optionally one can define a function to be called when
  // a unit increments (having a bell toll, etc.)
  hour: {
    makes: {day: 24},
    onIncrement() {
      console.log('BING!');
      console.log('Hour: ', this.time.hour);
    },
    // Units can be divided into multiple state changes. For example, a day has two or more states defined
    // by how many hours have passed.
    // 'states' can be an object or a function.
    // In this case, dawn and dusk are different depending
    // on the season
    states() {
      if (this.states.is('winter')) {
        return {
          day: 9, // 0900 -- by default this number represents hours. however, each property returned can also be a function that has access to any time unit.
          night: 20, // 2000
        };
      }
      return {
        day: 6, // 0900
        night: 23, // 2200
      };
    }
  },


  day: {
    makes() {
      const days = this.time.month % 2 ? 31 : 30;
      return {month: days};
    },
    onIncrement() {
      const names = 'MTWHFSU';
      console.log('Day:', names[this.time.day - 1]);
    },
  },
  month: {
    // The 'of' property can also be a function called
    // In this case, even months have 30 days and odd have 31.
    makes: { year: 12},

    // For simpler state changes, an object marking the
    // transitional thresholds is fine.
    states: {
      winter: 11,
      spring: 3,
      summer: 5,
      fall: 9
    }
  }
};

fantasy-time-crunch's People

Contributors

billy-le avatar dependabot[bot] avatar nelsonsbrian avatar rohitsaini7 avatar seanohue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fantasy-time-crunch's Issues

custom makes function doesn't seem to work either

for me, that is

day: {
					makes() {
						const days = this.time.month % 2 ? 31 : 30
						return { month: days }
					},
					onIncrement() {
						state.GameServer.emit("gameday",this.time)
					},
				},

Seems like it increments right past 30 and 31 days...

FILE: Prettier config file missing

What is the issue?

Nowadays everyone uses Prettier, An automated code formatting tool.

The issue is everyone have different global settings of prettier according to their style. BUT this can cause useless changes to opensource projects as many people works on same code.

So having a prettier config file inside project directory can resolve this issue.

How to solve this issue/ add this featuer?

adding a file .prettierrc and .prettierignore will solve this issue

more comprehensive unit tests

Given that there are a few bugs in the issues, I think more comprehensive unit testing would help. This is kind of a broad scope, but anything that is demonstrated in the README should be unit tested and proven to work as described.

a way to synchronize the system to a timestamp

I am currently using something like this...which doesn't use any particular custom units, or their respective make functions. But it lets me synchronize the time to the real world, which I like. Also it prevents the game time from restarting every time the mud reboots (and I don't have to worry about saving it to disk or anything).

If this seems like a good feature to you, maybe I'll try to write it in a modular fashion to account for custom units and make functions.

here's my current manual way of doing it

function getSynchronize(datetime){
    let yfloat = (datetime * 48) / 31536000000;
    let ywhole = Math.floor(yfloat);
    let yremainder = yfloat - ywhole;

    let mfloat = yremainder * 12;
    let mwhole = Math.floor(mfloat);
    let mremainder = mfloat - mwhole;

    let dfloat = mremainder * 30;
    let dwhole = Math.floor(dfloat);
    let dremainder = dfloat - dwhole;

    let hfloat = dremainder * 24;
    let hwhole = Math.floor(hfloat);
    let hremainder = hfloat - hwhole;

    let ifloat = hremainder * 60;
    let iwhole = Math.floor(ifloat);
    let iremainder = ifloat - iwhole;

    return {minute: iwhole, hour: hwhole, day: dwhole, month: mwhole, year: ywhole - 2000};
}

An integrated function could be called with something like

let syncTo.timestamp = Date.now();
syncTo.offsets[customUnit] = -230
syncTo.offsets[otherCustomUnit] = +23
syncTo.conversionRatio = 48 // 1unit
syncTo.conversionUnit = 'minute'

or just add options in the config itself is probably a better idea...

state.TimeCrunch = new TimeCrunch(config,syncTo);

the day of the week thing

 onIncrement() {
      const names = 'MTWHFSU';
      console.log('Day:', names[this.time.day - 1]);
    },

seems like there isn't any current conversion for days (1-30~) to weekdays. for me this.time.day returns 1 to 30~ not 1-7.

accessing unit states from returned object

Here's my current config, it seems like this.states.is('winter') isn't working from the returned object.

"use strict"
const TimeCrunch = require("~bundles/timecrunch/lib/TimeCrunch")
const { Logger } = require("ranvier")

module.exports = {
	listeners: {
		startup: state => function () {
			const config = {
				// One and only one unit is the smallest measured subdivision of time, defined as a 'tick'
				minute: {
					tick: true,
					makes: { hour: 60 },
				},

				// Optionally one can define a function to be called when
				// a unit increments (having a bell toll, etc.)
				hour: {
					makes: { day: 24 },
					onIncrement() {
						state.GameServer.emit("gamehour",this.time)
					},
					// Units can be divided into multiple state changes. For example, a day has two or more states defined
					// by how many hours have passed.
					// 'states' can be an object or a function.
					// In this case, dawn and dusk are different depending
					// on the season
					states() {
						if (this.states.is("winter")) {
							return {
								day: 9, // 0900 -- by default this number represents hours. however, each property returned can also be a function that has access to any time unit.
								night: 20, // 2000
							}
						}
						return {
							day: 6, // 0900
							night: 23, // 2200
						}
					}
				},
				day: {
					makes() {
						const days = this.time.month % 2 ? 31 : 30
						return { month: days }
					},
					onIncrement() {
						state.GameServer.emit("gameday",this.time)
					},
				},
				month: {
					// The 'of' property can also be a function called
					// In this case, even months have 30 days and odd have 31.
					makes: { year: 12 },

					// For simpler state changes, an object marking the
					// transitional thresholds is fine.
					states: {
						winter: 11,
						spring: 3,
						summer: 5,
						fall: 9
					},
					onIncrement(){
						state.GameServer.emit("gamemonth",this.time)
					}
				},
				year: {
					makes: {season: 50},
					onIncrement(){
						state.GameServer.emit("gameyear",this.time)
					}
				}
			}

			state.TimeCrunch = new TimeCrunch(config)

			let sync = getSynchronize(Date.now())
			for (let [k,v] of Object.entries(sync)) {
				loadUnit.call(state.TimeCrunch,k,v)
			}
            
			setInterval(function () {
				state.GameServer.emit("gameminute")
			}, 1250)

		},
		gameminute: state => () => {
			let obj = state.TimeCrunch.tick("minute",1)
			for (let [name,area] of state.AreaManager.areas){
				area.emit("gameminute",obj)
			}
		},
		gamehour: state => function(time){
			for (let [name,area] of state.AreaManager.areas){
				area.emit("gamehour",time)
			}
		},
		gameday: state => function(time){
			for (let [name,area] of state.AreaManager.areas){
				area.emit("gameday",time)
			}
		},
		gamemonth: state => function(time){
			for (let [name,area] of state.AreaManager.areas){
				area.emit("gamemonth",time)
			}
		},
		gameyear: state => function(time){
			for (let [name,area] of state.AreaManager.areas){
				area.emit("gameyear",time)
			}
		}
	}
}

function loadUnit(id, amount){
	this.time[id] = amount
}

function getSynchronize(datetime){
	let yfloat = (datetime * 48) / 31536000000
	let ywhole = Math.floor(yfloat)
	let yremainder = yfloat - ywhole

	let mfloat = yremainder * 12
	let mwhole = Math.floor(mfloat)
	let mremainder = mfloat - mwhole

	let dfloat = mremainder * 30
	let dwhole = Math.floor(dfloat)
	let dremainder = dfloat - dwhole

	let hfloat = dremainder * 24
	let hwhole = Math.floor(hfloat)
	let hremainder = hfloat - hwhole

	let ifloat = hremainder * 60
	let iwhole = Math.floor(ifloat)
	let iremainder = ifloat - iwhole

	return {minute: iwhole, hour: hwhole, day: dwhole, month: mwhole, year: ywhole - 2000}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.