sampling

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package sampling implements weighted probability tables with optional predicate gating, mutually-exclusive groups, and recursive table references. The "loot table" pattern at its mechanical core, domain- agnostic in implementation.

Common applications:

  • Games — loot drops, random encounters, procedural placement.
  • A/B testing — variant selection with weighted distribution and audience predicates.
  • Ad serving — slot allocation with category-exclusivity groups.
  • Survey balancing — quota-constrained random sampling.

Deterministic when paired with kit/rng.Stream — same SeedKey → reproducible roll output, suitable for replays and audits.

Index

Constants

This section is empty.

Variables

View Source
var ErrCycle = errors.New("sampling: cycle detected in table references")

ErrCycle is returned when a recursive table reference forms a cycle.

View Source
var ErrUnknownTable = errors.New("sampling: unknown table")

ErrUnknownTable is returned when a referenced table is not registered.

Functions

func Roll

func Roll[T any](
	ctx context.Context,
	tables *Tables[T],
	table TableID,
	src predicates.Source,
	stream *rng.Stream,
	out *[]Result[T],
) error

Roll rolls a table, appending each selected item to *out as a Result. Items are filtered by Predicate against src, mutually-exclusive groups pick a weighted winner, and ungrouped items with Weight > 0 are rolled independently against [0,1). Reference items recurse into the named table; cycles return ErrCycle.

stream is deterministic: same Stream + same input table → same output. Use kit/rng.Source.Sub(seedKey) to derive per-roll streams that audit cleanly.

ctx is forwarded to any Predicate.Eval calls and to recursive rolls, supporting tenant-aware predicates and tracing.

Types

type GroupID

type GroupID uint16

GroupID makes items mutually exclusive within the group: at most one item per group wins per roll. Use 0 for ungrouped items.

type Item

type Item[T any] struct {
	// Value is what the consumer receives when this item wins.
	Value T

	// Weight controls inclusion:
	//   > 0: probability-weighted (against other items in the same group,
	//        or rolled independently against 1.0 when ungrouped).
	//   = 0: guaranteed (always included).
	//   < 0: forbidden (skipped).
	Weight float32

	// Group makes this item mutually exclusive with other items in the
	// same group. Zero = ungrouped (rolled independently).
	Group GroupID

	// Reference, if non-zero, delegates this item to another table: when
	// this entry "wins", the referenced table is rolled instead. Value
	// is ignored. Cycles among references are detected at roll time.
	Reference TableID

	// Predicate, if non-nil, gates inclusion. Items failing the predicate
	// are skipped (treated as if Weight < 0).
	Predicate predicates.Predicate

	// Min/Max bound the count produced if this item is selected. Both
	// zero means count 1. If Max == 0 and Min > 0, count is exactly Min.
	Min, Max int
}

Item is one entry in a sampling table.

type Result

type Result[T any] struct {
	Value T
	Count int
}

Result is a winning item + its rolled count.

type TableID

type TableID uint32

TableID identifies a registered table. Used by Item.Reference for recursive table lookups.

type Tables

type Tables[T any] struct {
	// contains filtered or unexported fields
}

Tables holds registered sampling tables keyed by TableID.

func NewTables

func NewTables[T any]() *Tables[T]

NewTables returns an empty registry.

func (*Tables[T]) Get

func (t *Tables[T]) Get(id TableID) ([]Item[T], bool)

Get returns the items registered for id (read-only view).

func (*Tables[T]) Register

func (t *Tables[T]) Register(id TableID, items []Item[T])

Register binds items to id. Re-registering id replaces the prior set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL