Skip to content

sphireinc/namegen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Makefile CI Build and Test Codacy Security CodeQL Advanced

namegen

A fast, deterministic name generator written in Go.

namegen generates realistic-looking or fictional names across many language families using compiled-in profiles (no runtime plugins). Output can be made fully reproducible via seeds, making it suitable for games, testing, world-building, and data generation.


Features

  • Many language profiles (English, Japanese, Spanish, Nordic, Slavic, Tamil, Nahuatl, and more)
  • Deterministic randomness via seed (-s)
  • Realism control (-realism 0..100)
  • Gender hints (male, female, neutral)
  • Optional surnames by default ( turn them on with -l)
  • Reverse order (last name first)
  • Batch generation (-c)
  • Dev mode whih prints resolved config (-d)
  • Single static binary - no CGO, no .so plugins

Project layout

  • cmd/namegen/ – CLI entrypoint (imports all compiled-in profiles)
  • api/ – profile interface, deterministic RNG helpers, shared utilities
  • plugins/<name>/ – profiles (each registers itself via init())

Build

From repo root:

make build

Output:

$ ls .
bin/namegen

Run

Show help:

$ ./bin/namegen -h

Examples:

# default (english):
./bin/namegen

# choose a profile:
./bin/namegen -mode japanese

# include last name:
./bin/namegen -mode spanish -l

# reverse (last first):
./bin/namegen -mode spanish -l -r

# generate 10 names:
./bin/namegen -mode english -l -c 10

# deterministic (repeatable):
./bin/namegen -mode english -l -s 42 -realism 80

# gender:
./bin/namegen -mode english -gender female -l -realism 90

# prints a list of all available profiles
./bin/namegen -p 

# dev mode prints the config JSON used:
./bin/namegen -mode japanese -l -c 10 -d

Flags

Flag Meaning
-mode <name> Profile/mode name (compiled-in). Defaults to english.
-l Include last name
-r Reverse output order (last first)
-gender <male, female, neutral> Gender hint passed to profile
-family <key> Optional “family override” (profiles may interpret it differently)
-realism 0...100 0 = fictional phonotactics, 100 = curated/real-looking
-s <seed> Seed (0 / omit = random each run)
-c <count> Number of names to generate
-d Dev mode: prints config JSON
-p List all avilable profiles

Available profiles

These are compiled into the binary via blank imports in cmd/namegen/main.go

  • amharic
  • arabic
  • aramaic
  • baltic
  • celtic
  • chinese
  • english
  • farsi
  • filipino
  • french
  • germanic
  • greek
  • hawaiian
  • hebrew
  • hindi
  • igbo
  • indonesian
  • italian
  • japanese
  • kazakh
  • korean
  • malay
  • maori
  • nahuatl
  • nordic
  • portuguese
  • samoan
  • slavic
  • spanish
  • swahili
  • tamil
  • thai
  • turkish
  • uzbek
  • vietnamese
  • yoruba

If you run a mode that doesn't exist, the CLI falls back to english.

How it works

The CLI passes api.ProfileConfig to the selected profile.

  • Profiles call api.NewRand(cfg) which:
    • returns a deterministic RNG when cfg.Seed != 0
    • returns a time-seeded RNG when cfg.Seed == 0
  • Profiles should use api.PickRand(slice, r) to select items.

Rule of thumb: If you want reproducibility, always pass -s <seed>

Writing a new profile (compiled-in)

  1. Create a folder:
$ mkdir -p plugins/myprofile
  1. Add plugins/myprofile/myprofile.go and paste this minimal skeleton:
package myprofile

import (
	"github.com/nsa-yoda/namegen/api"
)

type myProfile struct{}

const PROFILE = "myprofile"

func init() {
	api.RegisterProfile(PROFILE, Profile)
}

func (p myProfile) Info() map[string]string {
	return map[string]string{
		"name":  PROFILE,
		"notes": "What this profile does",
	}
}

func (p myProfile) Generate(cfg api.ProfileConfig) (api.NameResult, error) {
	r := api.NewRand(cfg)

	first := api.PickRand([]string{"Ada", "Grace", "Linus"}, r)
	last := ""
	if cfg.IncludeLast {
		last = api.PickRand([]string{"Lovelace", "Hopper", "Torvalds"}, r)
	}

	return api.NameResult{First: first, Last: last}, nil
}

var Profile myProfile
  1. Compile it into the binary by adding a blank import to cmd/namegen/main.go:
_ "github.com/nsa-yoda/namegen/plugins/myprofile"
  1. Build and run:
$ make build
$ ./bin/namegen -mode myprofile -l -s 123 -c 5

Library usage (import in your own Go project)

If you want to use NameGen as a library, you import the API package and then load plugins. The easiest way is to import all built-in plugins at once:

package main

import (
	"fmt"

	_ "github.com/nsa-yoda/namegen/all"
	"github.com/nsa-yoda/namegen/api"
)

func main() {
	// List available profiles (registered by imports)
	fmt.Println("profiles:", api.ListProfiles())

	// Grab a profile and generate a name
	p, err := api.GetProfile("english")
	if err != nil {
		panic(err)
	}

	out, err := p.Generate(api.ProfileConfig{
		Seed:        123,
		Realism:     90,
		Gender:      "neutral",
		IncludeLast: true,
	})
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s\n", out.First, out.Last)
}

Loading only one plugin (smaller binaries)

If you don't want every built-in profile, import only the plugin(s) you need:

package main

import (
	_ "github.com/nsa-yoda/namegen/plugins/english" // registers “english” plugin/porfile
	"github.com/nsa-yoda/namegen/api"
)

p, _ := api.GetProfile("english")
res, _ := p.Generate(api.ProfileConfig{Seed: 123, IncludeLast: true})

Notes

github.com/nsa-yoda/namegen/all is a convenience package that blank-imports every built-in plugin so their init() functions run and registers the profiles.

If you care about binary size / compile time, prefer importing only the specific plugin packages you need

Notes / gotchas

  • realism is profile-specific behavior. Every profile implements its own blend between curated names and procedural phonotactics.
  • ASCII output by design is the defualt. Some languages normally use diacritics or special punctuation; these profiles intentionally keep output ASCII-friendly.
  • Profile not found fallback. If -mode isn't registered, the CLI logs a warning and uses english.

License

This project is licensed under the MIT license, see LICENSE file

About

A fast, deterministic name generator written in Go

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors