Yet another Traveller NPC generator
This is a simple NPC generator for the Traveller RPG.
It follows rules described in this article.
I'll briefly describe the rules here.
Ability scores
Instead of randomly generating ability scores, this generator uses several standard arrays:
Citizen Category |
Average Score |
Characteristic Array |
Below Average |
6 |
8, 7, 6, 6, 5, 4 |
Average |
7 |
9, 8, 7, 7, 6, 5 |
Above Average |
8 |
10, 9, 8, 8, 7, 6 |
Exceptional |
9 |
11, 10, 9, 9, 8, 7 |
Skills
According to the previous experience of the NPC, the generator will assign a number of skill points according to this table, "Average Skill Levels by Term":
Average Skill Levels by Experience
Experience | Number of Skills by Skill Level |
3 | 2 | 1 | 0 |
Recruit | 0 | 0 | 0 | 4 |
Rookie | 0 | 0 | 2 | 4 |
Intermediate | 0 | 1 | 2 | 4 |
Regular | 0 | 2 | 2 | 5 |
Veteran | 0 | 3 | 2 | 5 |
Elite | 1 | 2 | 3 | 6 |
Build & Run
To build the project execute the following command:
make build
This will generate this binary out/generate-npc
.
To run the project execute the following command:
./out/generate-npc --help
These are the options for the command:
Option |
Long Option |
Description |
Default |
-c |
--category |
Citizen Category: 0-Below average, 1-Average, 2-Above Average, 3-Exceptional |
1 |
-e |
--experience |
Experience: 0-Recruit, 1-Rookie, 2-Intermediate, 3-Regular, 4-Veteran, 5-Elite |
3 |
-r |
--role |
Crew role in a starship: pilot, navigator , engineer , steward , medic , marine , gunner , scout , technician , leader , diplomat , entertainer , trader , thug |
required |
-g |
--gender |
Gender of the NPC: female, male, unspecified |
unspecified |
-d |
--debug |
Enable debug mode |
false |
-h |
--help |
Show the help message |
|
Generator library
You can also use this project as a library in your Go applications.
You can install it by running the following command:
go get github.com/carloscasalar/traveller-npc-generator
Here are some examples:
Example 1: Generate a Character
package main
import (
"fmt"
"github.com/carloscasalar/traveller-npc-generator/pkg/generator"
"os"
)
func main() {
npcGenerator, err := generator.NewNpcGeneratorBuilder().Build()
if err != nil {
fmt.Printf("Error creating NPC: %v", err)
os.Exit(1)
}
request := generator.NewGenerateCharacterRequestBuilder().
CitizenCategory(generator.CitizenCategoryAboveAverage).
Experience(generator.ExperienceRookie).
Role(generator.RolePilot).
Gender(generator.GenderUnspecified).
Build()
character, err := npcGenerator.Generate(*request)
if err != nil {
fmt.Printf("Error generating character: %v", err)
os.Exit(1)
}
fmt.Println("Generated Character:", character)
}
Example 2: Generate a Character with custom name generator
The library uses a very simple name generator. You can provide your own name generator by implementing the NameGenerator
interface.
package main
import (
"fmt"
"github.com/carloscasalar/traveller-npc-generator/pkg/generator"
"os"
)
func main() {
npcGenerator, err := generator.NewNpcGeneratorBuilder().
NameGenerator(new(CustomNameGenerator)).
Build()
if err != nil {
fmt.Printf("Error creating NPC: %v", err)
os.Exit(1)
}
for _, gender := range generator.GenderValues() {
request := generator.NewGenerateCharacterRequestBuilder().
CitizenCategory(generator.CitizenCategoryExceptional).
Experience(generator.ExperienceVeteran).
Role(generator.RoleLeader).
Gender(gender).
Build()
character, err := npcGenerator.Generate(*request)
if err != nil {
fmt.Printf("Error generating character: %v", err)
os.Exit(1)
}
fmt.Printf("Generated Character: %v\n", character)
}
}
type CustomNameGenerator struct {
}
func (c CustomNameGenerator) Generate(gender generator.Gender) (firstName, surname string) {
switch gender {
case generator.GenderMale:
return "Dwayne", "Hicks"
case generator.GenderFemale:
return "Hellen", "Ripley"
default:
return "Forge", "Jynxori"
}
}
Example 3: Generate a Character with catalog of surnames and names based name generator
This library comes with a name generator that uses a catalog of names and surnames. You can use it by creating a new instance of CatalogNameGenerator
.
package main
import (
"fmt"
"github.com/carloscasalar/traveller-npc-generator/pkg/generator"
"math/rand/v2"
"os"
)
func main() {
femaleNames := []string{"Hellen", "Jane", "Alice"}
maleNames := []string{"Dwayne", "John", "Bob"}
nonBinaryNames := []string{"Forge", "Jynxori", "Alex"}
surnames := []string{"Hicks", "Doe", "Smith"}
catalogNameGenerator, err := generator.NewCatalogSourcedNameGenerator(surnames, nonBinaryNames, femaleNames, maleNames)
if err != nil {
fmt.Printf("Error creating catalog sourced name generator: %v", err)
os.Exit(1)
}
npcGenerator, err := generator.NewNpcGeneratorBuilder().NameGenerator(catalogNameGenerator).Build()
if err != nil {
fmt.Printf("Error creating NPC generator: %v", err)
os.Exit(1)
}
for _, gender := range generator.GenderValues() {
category := pickRandomItem(generator.CitizenCategoryValues())
experience := pickRandomItem(generator.ExperienceValues())
role := pickRandomItem(generator.RoleValues())
request := generator.NewGenerateCharacterRequestBuilder().
CitizenCategory(category).
Experience(experience).
Role(role).
Gender(gender).
Build()
character, err := npcGenerator.Generate(*request)
if err != nil {
fmt.Printf("Error generating character: %v", err)
os.Exit(1)
}
fmt.Printf("Generated character: %v\n", character)
}
}
func pickRandomItem[T any](items []T) T {
itemIndex := rand.IntN(len(items) - 1)
return items[itemIndex]
}