@sushiinu/lembas v0.4.1
@sushiinu/lembas
RPG world generation tool
Table of Contents
Install
$ npm install @sushiinu/lembas --save
Usage
LembasModels
Models
Saving a Character to storage:
import { LembasModels as m } from '@sushiinu/lembas';
export class YourClass {
...
createCharacter(object : m.ICharacter) : m.Character {
return new m.Character(object);
}
}
Interfaces
Every model has its own interface for data structures. It always has the name like "I" + model name (for example, ICharacter for Character).
import { LembasModels as m } from '@sushiinu/lembas';
export class YourClass {
...
getCharacterInfo(char : m.Character) : m.ICharacter {
let data : m.ICharacter = {
id: char.id,
name: char.name,
age: char.age,
weight: char.weight,
profession: char.profession,
race: char.race,
items: char.items,
skills: char.skills,
spells: char.spells,
traits: char.traits
}
return data;
}
}
LembasStorage
Saving a Character to storage:
import { LembasModels as m, LembasStorage } from '@sushiinu/lembas';
export class YourClass {
...
saveCharacter(object : m.Character) {
return LembasStorage.characters.save(object);
}
}
LembasGenerator
Generate a Character:
import { LembasGenerator, LembasModels as m } from '@sushiinu/lembas';
export class YourClass {
...
init(){
let rules = {
characters: {
// every function must follow this structure:
// function(rng, params?) : any
// generates value
age: function(rng, params?) : number { ... },
weight: function(rng, params?) : number { ... },
// generates id
profession: function(rng, params?) : string { ... },
race: function(rng, params?) : string { ... },
// generates array of ids
items: function(rng, params?) : string[] { ... },
skills: function(rng, params?) : string[] { ... },
spells: function(rng, params?) : string[] { ... },
traits: function(rng, params?) : string[] { ... },
// params for your functions
"items.params": {yourItemCount: 3},
"spells.params": {yourSpellRank: 2}
}
}
LembasGenerator.init(rules)
}
generateCharacter(id: string, name: string) {
this.init()
characterData : m.ICharacter = {
id: id,
name: name,
// all of the properties you want to generate, should be set as undefined
age: undefined,
profession: undefined,
race: undefined,
items: undefined,
skills: undefined,
traits: undefined
// if you don't want to generate some properties - don't write them at all
// for example, properties 'spells' and 'weight' would be undefined instead of generated
// spells: undefined,
// weight: undefined
}
return LembasGenerator.characters.generate(object)
}
}
You might think "what is rng in those functions?". Well, that's a seeded randomizer. When you initiate LembasGenerator, you even can choose its seed LembasGenerator.init(rules, seed)
(which is number
).
That randomizer is used at every point of generating a model object and it's highly recommended to use it in your rule functions to generate random numbers. That way you can achieve persistence of your generations: generated objects will be the same if you generate them in exact same order with exact same seed.
If you want to use it in your app, just import it.
import { LembasRandomizer } from '@sushiinu/lembas';
export class YourClass {
private rng : LembasRandomizer
constructor(seed? : number) {
this.rng = new LembasRandomizer(seed)
}
nextInt(min: number, max: number) : number {
return this.rng.nextInt(min, max);
}
nextDouble() : number {
return this.rng.nextDouble();
}
}
LembasHistory
LembasHistory contains logs of every generation made by LembasGenerator. It's a nice tool to have history of all those objects.
import { LembasHistory } from '@sushiinu/lembas';
export class YourClass {
...
getLog() {
return LembasHistory.log;
}
}
Each object in log consists of serialized model object object
and amount of times randomizer was used to generate it rand
.
export abstract class LembasHistory {
...
public static save(object : any, rand : number) {
this._log.push({
object: JSON.stringify(object),
rand: rand
})
}
}
But true purpose of LembasHistory is to maintain persistance, when using LembasGenerator with seeded randomizer. Every logged object contains total amount of uses of randomizer, so if you have history log, you can use it to re-create those objects bypassing generator, same as if you would generate them again (in the same order).
The only thing you need to do then is to reset randomizer and skip the amount of randomizer uses for each object in log.
import { LembasGenerator,LembasHistory } from '@sushiinu/lembas';
export class YourClass {
constructor() {}
resetGenerator(seed : number) {
let log = LembasHistory.log;
let randUses = log.reduce((acc, o) => acc + o.rand, 0)
LembasGenerator.reset(seed, randUses)
}
}
If you have your own randomizer, you also can use reset method:
import { LembasRandomizer } from '@sushiinu/lembas';
export class YourClass {
...
private rng : LembasRandomizer
constructor(seed? : number) {
this.rng = new LembasRandomizer(seed)
}
reset(seed: number, skip : number) {
this.rng.reset(seed, skip)
}
}
Contribute
- Fork it and create your feature branch: git checkout -b my-new-feature
- Commit your changes: git commit -am 'Add some feature'
- Push to the branch: git push origin my-new-feature
- Submit a pull request
License
MIT