problab

package module
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

README

🌐 Language: En | 中文

For version changes, see the release notes.


Problab

Maintained by Zintix Labs — @nextso

Problab is a high-performance slot math engine for math designers and engineers.

Build once, then simulate, reproduce, and ship to production
with the same source of truth.

Simulation runs the same execution path as production.


What is Problab?

If it runs in simulation,
it runs the same way in production.

Problab is a slot math execution engine designed for both large-scale simulation and real production use.

It is the same engine that can be used for:

  • large-scale math simulation
  • deterministic reproduction (seed-based)
  • backend game server execution
  • development & debugging

There is no separate “simulation logic” and “production logic”.


Why Problab?

Slot math engines usually fail in one of these ways:

  • Simulators are fast but not production-ready
  • Production engines are correct but too slow to simulate
  • Simulation logic and server logic diverge over time
  • Reproducing a real production issue is painful or impossible

Problab is designed to solve this exact problem.


Core Design Goals

  • Single Source of Truth
    One engine, one logic path, one result.

  • High Performance by Design
    Zero-allocation hot paths, cache-friendly data layout.

  • Explicit Dependency Injection
    No hidden globals, no magic init side effects.

  • Developer-Friendly
    Add a new game by providing:

    • one config file
    • one logic file
  • Same execution path in simulation and production
    Simulation is not a mock or a reimplementation.
    It runs the same deterministic logic path as production.


Performance Snapshot (MacBook Air M3)

All numbers below are real measurements, not synthetic benchmarks.

Single Core
Game Type Throughput
Simple (5x3, 15 lines) ~7.0M spins/sec
Cascade / Cluster ~1.7M spins/sec
4-Core Parallel Execution
Game Type Throughput
Simple ~19M spins/sec
Cascade / Cluster ~5.8M spins/sec
Real Run Output (Example)
make run w=4 r=25000000
[WORKERS:4] [GAME:demo_normal] [PLAYMODE:0] [SPINS:100,000,000]
used: 5.26 seconds                                                                                                                      
sps : 19,010,181 spins/sec
+--------------------------------+
|          demo_normal           |
+--------------+-----------------+
| Game Name    | demo_normal     |
| Game ID      | 0               |
| Total Rounds | 100,000,000     |
| Total RTP    | 95.56 %         |
| RTP 95% CI   | [95.42%,95.69%] |
| Total Bet    | 4,000,000,000   |
| Total Win    | 3,822,201,660   |
| Base Win     | 2,439,779,100   |
| Free Win     | 1,382,422,560   |
| NoWin Rounds | 71,034,259      |
| Trigger      | 835,933         |
| STD          | 6.797           |
| CV           | 7.113           |
+--------------+-----------------+

Built-in Optimizer (optimizer/v2 + cmd/opt)

Configure the target, math intent, collection policy, and output directory in cmd/opt/opt_cfg.yaml, then run:

make opt
# equivalent: go run ./cmd/opt

The optimizer validates the configuration and collects outcomes, then either exports the collection directly (rgs-collected) or solves and verifies a distribution before export. Results go to output.directory; see the configuration comments for output options.

For your own application, use optimizer/v2/cli.Run with your configuration bytes, Problab instance, collection tags, and result converter.

Finite player experience (playerexp + cmd/exp)

Edit cmd/exp/exp_cfg.yaml, register your game-specific strategies/tags, then run make exp to export player-experience CSV reports to build/exp. See playerexp for composition and phase-one boundaries.


Typical Use Cases

  • Slot math simulation & validation
  • RTP / volatility analysis
  • Deterministic replay & debugging
  • Backend game server execution
  • CI regression testing for math changes

Built-in Math Reports (Stats & Verification)

Problab ships with first-class math verification reports for validation and regression.

Out of the box you can generate:

  • RTP + 95% CI
  • STD / CV (volatility)
  • Hit / No-Win / Trigger rates
  • Win distribution buckets (base / free / total)
  • Recorder-style summaries for audit/debug workflows

This is designed for practical math workflows:
validate → compare → regress → explain with reproducible inputs.

Problab treats verification output as a first-class product feature, not an afterthought.

Example Output

Total RTP: 95.56%
RTP 95% CI: [95.42%, 95.69%]
STD: 6.797
CV:  7.113
...

Quick Start

Successful execution in 1 minute; production environment ready in 3 minutes.

This repository focuses on the engine itself. For building real games, start with the scaffold.

Use problab-scaffold — a clean starter template built on top of Problab.

👉 https://github.com/zintix-labs/problab-scaffold

The scaffold provides:

  • pre-wired configs / logic / server / simulation
  • one-command run (make run, make dev, make svr)
  • a structure ready for private commercial development

This is the recommended way to build real games with Problab.


Determinism & Reproducibility

  • Seed-driven execution
  • Replayable results
  • Identical behavior between simulation and server
  • ChaCha20 default with explicit PCG64 compatibility mode

This makes Problab suitable for:

  • math audits
  • regression testing
  • production issue investigation

Custom PRNG factories accept opaque []byte seed material and own deterministic stream derivation. Existing public int64 seed constructors remain available; use core.PCG64() when old PCG output or optimizer artifacts must remain bit-exact. Production new-game cycles call the PRNG's mandatory Reseed hook, while explicit seeded, simulator, optimizer, and replay paths remain deterministic. Local design notes and migration records are intentionally not part of the distributed module.


Status

  • APIs may evolve befor v1.0.0
  • Focus is on correctness, performance, and core architecture

Documentation, tests, and starter templates will be expanded iteratively.


Roadmap

  • Jackpot support (settings + snapshot/delta)
  • More shared ops
  • (RFC) Trigger methods for state transitions

Contributing

For v0.x.y, we only accept:

  • Bug reports (with minimal repro / logs if possible)
  • Documentation improvements (fixes, examples, translations)

Feature requests are welcome for discussion, but may not be prioritized yet.


License

Apache License 2.0
See LICENSE and NOTICE.

Documentation

Overview

Package problab 提供 Problab 引擎的「組裝入口(assembler)」與「運行入口(runtime entry)」。

你可以把 Problab 視為一個「可被後端/模擬器使用的 runtime」,它負責把下列三個必需的地基組裝在一起,並提供建立 Machine 的入口:

  1. Catalog:遊戲目錄(Single Source of Truth / SSOT),定義有哪些遊戲、各自對應的設定檔名稱(ConfigName)。
  2. LogicRegistry:邏輯註冊表,提供「如何依據設定(LogicKey)建出遊戲邏輯」的 builders。
  3. CoreFactory:亂數核心工廠(PRNG factory),保證可重現(reproducible)與可審計(auditable)。

設計重點:

  • 遊戲設定來源不綁定檔案路徑,一律以 fs.FS 注入;大型 Optimal Artifact 可另外用 WithOptimalDir 指定普通檔案目錄以啟用 mmap。
  • Problab 會持有一份 Catalog(你要跑哪一批遊戲/設定檔)與一份 LogicRegistry(你支援哪些遊戲邏輯)。
  • Machine 是對外提供 Spin 的最小單位;遊戲邏輯開發者(數學家)主要操作的是 sdk 內的型別與資料結構。

典型使用情境:

  • 後端服務(HTTP / gRPC):由 Problab 建立 Machine,Machine 對外提供 Spin。
  • 模擬器(sim):由 Problab 建立多台 Machine 進行大量模擬。

注意:此套引擎目前以 Slot 領域為中心(Spin -> Result),不是泛用遊戲框架。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Configs

func Configs(cfgs ...fs.FS) []fs.FS

Configs 用來把一或多個設定檔來源(fs.FS)打包成 New() 需要的參數。

為什麼是 fs.FS:

  • 你可以用 go:embed 把 configs 直接編進 binary(部署最穩定,不依賴工作目錄)。
  • 也可以用 os.DirFS 在本機開發時讀取目錄。
  • 甚至可以用自製的 MultiFS 來合併多個來源。

Problab 不解析「路徑」:它只依賴 fs.FS + ConfigName(檔名)來取得設定內容。

func Logics

func Logics(regs ...*slot.LogicRegistry) []*slot.LogicRegistry

Logics 用來把一或多個邏輯註冊表(LogicRegistry)打包成 New() 需要的參數。

一個 LogicRegistry 代表「一個邏輯模組」提供的 builders 集合。 例如:

  • basegame 模組提供 basegame 的 builder
  • freegame 模組提供 freegame 的 builder

New() 會把多個 registries 合併成單一 registry;若出現重複 LogicKey,會以 error 直接失敗(避免行為不確定)。

Types

type DevSimReport

type DevSimReport struct {
	Before string            `json:"before"`
	After  string            `json:"after"`
	Stat   *stats.StatReport `json:"statistic"`
}

type DevSimulator

type DevSimulator struct {
	// contains filtered or unexported fields
}

DevSimulator

只提供給Dev模式使用的模擬器,單線(不併發),重點在可審計、可重現

func (*DevSimulator) RestoreSim

func (d *DevSimulator) RestoreSim(be64 string, betmode int, round int) (DevSimReport, error)

func (*DevSimulator) RestoreSpins

func (d *DevSimulator) RestoreSpins(be64 string, betmode int, round int) (DevSpinReport, error)

func (*DevSimulator) Sim

func (d *DevSimulator) Sim(betmode int, round int) (DevSimReport, error)

func (*DevSimulator) Spins

func (d *DevSimulator) Spins(betmode int, round int) (DevSpinReport, error)

type DevSpinReport

type DevSpinReport struct {
	Before   string           `json:"start_b64u"`
	After    string           `json:"after_b64u"`
	Round    int              `json:"round"`
	Rtp      float64          `json:"rtp"`
	TotalBet int              `json:"total_bet"`
	TotalWin int              `json:"total_win"`
	BaseWin  int              `json:"base_win"`
	FreeWin  int              `json:"free_win"`
	Results  []dto.SpinResult `json:"results"`
}

type Gacha added in v0.5.0

type Gacha struct {
	Picker  *sampler.AliasTableF64 `json:"picker"`   // 抽樣表
	SeedLen int                    `json:"seed_len"` // 抽到對應第幾個種子,就要 * SeedLen 取[n*SeedLen:(n+1)*SeedLen]
}

Machine 封裝一台「可對外提供 Spin」的遊戲機台。

你可以把 Machine 視為 Game 的「外殼(shell)」:

  • 對外:提供 Spin 入口(HTTP/模擬器通常只操作 Machine)。
  • 對內:持有 RNG(Core)與真正執行遊戲邏輯的核心(sdk/slot.Game)。

並發語意:

  • Machine 預設不是 lock-free 結構;它內含可重用的 request/result buffer(熱路徑),因此同一台 Machine 不應被多 goroutine 同時 Spin。
  • 若要併發模擬,由更高層建立多台 Machine 分散到不同 worker 並管理其生命週期。

Buffer 語意(非常重要,影響 DX 與正確性):

  • SpinRequest / SpinResult 會被重用(避免 GC),每次 Spin 會覆寫內容。
  • 你若需要在 Spin 後保留結果,請在離開臨界區前轉成 DTO(或自行 copy 你需要的欄位)。

Gacha is the legacy JSON compatibility shape for optimizer.Gacha. Deprecated: runtime Machines use the immutable internal Artifact instead.

func (*Gacha) Pick added in v0.5.0

func (g *Gacha) Pick(c *core.Core) (start int, end int)

Pick 從 Gacha 中抽取一個索引範圍。

type Machine

type Machine struct {
	BetUnits    []int            // 押注單位(由遊戲設定衍生;通常給外部列舉 UI/測試)
	SpinRequest *buf.SpinRequest // 可重用的請求 buffer(每次 Spin 會覆寫/填充)
	SpinResult  *buf.SpinResult  // 可重用的結果 buffer(熱路徑;每次 Spin 會覆寫)
	// contains filtered or unexported fields
}

func (*Machine) RestoreCore

func (m *Machine) RestoreCore(src []byte) error

RestoreCore 恢復Core狀態暫存 當前僅提供恢復Core狀態

之後要實作斷手重連時候提供checkpoint加入必要恢復資訊時實作 Restore() <- 保留語意

func (*Machine) SnapshotCore

func (m *Machine) SnapshotCore() ([]byte, error)

SnapshotCore 取得Core狀態暫存 當前僅提供取得Core狀態

之後要實作斷手重連時候提供checkpoint加入必要恢復資訊時實作 SnapShot() <- 保留語意

func (*Machine) Spin

func (m *Machine) Spin(r *dto.SpinRequest) (dto.SpinResult, error)

Spin 為主要公開入口,會驗證投注請求,執行遊戲並回傳Spin結果。

func (*Machine) SpinInternal

func (m *Machine) SpinInternal(betMode int) *buf.SpinResult

SpinInternal 直接取得內部 SpinResult;常用於模擬器或測試

請勿在正式環境使用

此行為跳過所有檢查,並只使用預設1單位下注 如果啟用優化,會從 Gacha 中 Pick 種子並先設置 Core 狀態

func (*Machine) SpinOffline added in v0.15.0

func (m *Machine) SpinOffline(betMode, betMult int) (result *buf.SpinResult, err error)

SpinOffline executes a deterministic new spin with a validated wager. It is for sequential offline tools, not production requests or checkpoint recovery. The result and its nested buffers are borrowed until the next Machine call. Callers must not share this Machine or retain/mutate its borrowed result.

func (*Machine) UsesOptimal added in v0.15.0

func (m *Machine) UsesOptimal() bool

UsesOptimal reports the loaded runtime source, not merely a config flag.

type MachinePool

type MachinePool struct {
	// contains filtered or unexported fields
}

MachinePool 專門管理「某一款遊戲」的所有機台實例。 它透過兩個通道管理機台生命週期:

  1. pool:健康且可用的機台,供 Spin() 借出 / 歸還。
  2. broken:在運作過程中發生錯誤或 panic 的壞機台,送往此通道以便後續檢查、維修或丟棄。

若某台機台於遊戲執行期間發生 panic 或 fatal error,該機台會被送至 broken,並立即補上一台新機以維持容量。 整體機制確保整個系統在高併發下仍保持穩定與可用性。

func (*MachinePool) Available

func (mp *MachinePool) Available() int

Available 回傳當下 pool 可用機台數(len(pool))。在高併發下為近似值。

func (*MachinePool) Close

func (p *MachinePool) Close()

Close 進入關閉狀態:

  • 通知之後所有 Spin() 應該直接回error
  • defer 歸還/補機時會觀察 done,避免對已關閉狀態進行 send

func (*MachinePool) Closed

func (p *MachinePool) Closed() bool

Closed 回報池是否已進入關閉狀態。

func (*MachinePool) ClosedReason

func (mp *MachinePool) ClosedReason() string

func (*MachinePool) Fatals

func (mp *MachinePool) Fatals() int

func (*MachinePool) Inflight

func (mp *MachinePool) Inflight() int

func (*MachinePool) Metrics

func (mp *MachinePool) Metrics() MachinePoolMetrics

Metrics 回傳一期的觀測快照;上層可用於 log、/metrics、或餵給 Prometheus/OTEL exporter。

func (*MachinePool) Panics

func (mp *MachinePool) Panics() int

func (*MachinePool) PoolSize

func (mp *MachinePool) PoolSize() int

func (*MachinePool) ReBuild

func (mp *MachinePool) ReBuild() int

func (*MachinePool) Spin

func (p *MachinePool) Spin(ctx context.Context, req *dto.SpinRequest) (dto dto.SpinResult, err error)

type MachinePoolMetrics

type MachinePoolMetrics struct {
	GameName string   `json:"game_name"`
	GameID   spec.GID `json:"game_id"`

	PoolSize      int    `json:"pool_size"`      // 目標容量(初始化指定)
	Available     int    `json:"available"`      // 當下可借出的機台數(len(pool))
	Inflight      int    `json:"inflight"`       // 使用中(借出未歸還)
	BrokenBacklog int    `json:"broken_backlog"` // broken channel 當下 backlog(len(broken))
	Rebuild       int    `json:"rebuild"`        // 補機次數
	Panics        int    `json:"panics"`         // panic 次數
	Fatals        int    `json:"fatals"`         // fatal 次數
	Closed        bool   `json:"closed"`         // 是否已關閉
	CloseReason   string `json:"close_reason"`   // 關閉原因

	CloseInflight int `json:"close_inflight"` // Close() 當下 inflight(-1 表示尚未關閉)
	CloseAvail    int `json:"close_avail"`    // Close() 當下 available(-1 表示尚未關閉)
	Closebroken   int `json:"close_broken"`   // Close() 當下 broken backlog(-1 表示尚未關閉)
}

MachinePoolMetrics 是一期提供的「拉取式(pull)」觀測快照。

設計原則:

  • 不綁任何 metrics/telemetry SDK(Prometheus / OpenTelemetry 等),由上層自己決定如何輸出。
  • 欄位值以讀取當下為主;其中 Available/brokenBacklog 來自 len(chan),在高併發下是「近似值」但足夠用於營運觀測。
  • 關閉瞬間的快照(CloseInflight/CloseAvail/Closebroken)只會在 Close 時寫入一次,用於事後排查。

type OptimalRuntime added in v0.5.0

type OptimalRuntime struct {
	Gachas []*Gacha // 對應每個 betmode,len(Gachas) == len(BetUnits)
	Bank   [][]byte // 對應每個 betmode,每個 []byte 是完整的 SeedBank
}

OptimalRuntime is retained for source compatibility with the legacy public shape. Deprecated: Problab now owns one immutable shared Artifact per bundle.

type Problab

type Problab struct {
	// contains filtered or unexported fields
}

Problab 是「組裝器(assembler)」與「運行入口(runtime entry)」:

它把三個必需的地基組合起來:

  1. Catalog:遊戲目錄(Single Source of Truth / SSOT),定義有哪些遊戲、各自對應的設定檔名稱。
  2. LogicRegistry:邏輯註冊表,提供「如何依據設定(LogicKey)建出遊戲邏輯」的 builders。
  3. CoreFactory:亂數核心工廠(PRNG factory),保證可重現(reproducible)與可審計(auditable)。

遊戲設定來源不綁定任何檔案路徑,一律由 fs.FS 提供;Optimal Artifact 則可選擇 fs.FS memory backend 或普通目錄 mmap backend。

使用流程通常分成兩階段:

  • 註冊/組裝階段(registration/build):建立 catalog、合併 registries、檢查重複與缺漏。
  • 執行階段(runtime):依據遊戲 ID 產生 Machine,並在 Machine 上執行 Spin。

重要設計原則:

  • Catalog 的 ID 唯一性只保證在「同一個 Problab instance」內(不同 Problab 之間不做全域保證)。
  • 你要跑哪一批遊戲、哪一套設定檔、哪一批邏輯,必須由 New() 的參數明確決定。
  • runtime 一旦開始(例如已建立 Machine 並對外服務),不建議再變更 Catalog/Registry(避免非預期行為)。

實務例子(概念示意,細節依你的實作為準):

// 1) 準備 configs(通常是 go:embed 或 DirFS)
// 2) 準備一或多個邏輯模組的 LogicRegistry
// 3) 組裝 Problab,取得可建立 Machine 的入口
//	lab, _ := problab.New(cf, problab.Configs(cfgFS), problab.Logics(reg1, reg2))
//	m, _ := lab.NewMachine(1001, false)
//	// m.Spin(...) -> 取得結果(通常再轉成 DTO 回傳)

func New

func New(cf core.PRNGFactory, cfgs []fs.FS, logics []*slot.LogicRegistry, opts ...ProblabOption) (*Problab, error)

New 建立一個 Problab instance。

這是「組裝階段(registration/build)」的入口:

  • 會建立 Catalog(通常同時做檔名存在性/重複性檢查,避免 runtime 才爆)。
  • 會合併多個 LogicRegistry 成為單一 registry(重複 LogicKey 直接視為錯誤)。
  • 會保存 CoreFactory,確保由這個 Problab 建出來的 Machine 在 RNG 行為上具有一致性。

參數要求(是合約的一部分):

  • cf 不能為 nil:沒有 RNG 工廠就無法建立可重現/可審計的核心。
  • cfgs 至少一個:沒有設定檔來源,Catalog 無法解析 GameSetting。
  • logics 至少一個:沒有邏輯 builders,就算解析出設定也無法建出可執行的遊戲邏輯。

回傳的 Problab 會持有:cat(目錄)、reg(合併後 registry)、cf(RNG 工廠)、optimalFS(可選的優化文件系統)。

func NewAuto

func NewAuto(cf core.PRNGFactory, cfgs []fs.FS, logics []*slot.LogicRegistry, opts ...ProblabOption) (*Problab, error)

NewAuto 建立一個直接進入執行階段的 Problab instance。

回傳的 Problab 會持有:cat(目錄)、reg(合併後 registry)、cf(RNG 工廠)、optimalFS(可選的優化文件系統)。

func (*Problab) All

func (p *Problab) All() []catalog.Entry

func (*Problab) BuildRuntime

func (p *Problab) BuildRuntime(poolSize int) (*SlotRuntime, error)

func (*Problab) Close added in v0.6.0

func (p *Problab) Close() error

Close releases resources owned by this Problab instance. Runtime and pool users must be stopped first; Close is safe to call more than once.

func (*Problab) Closed added in v0.6.0

func (p *Problab) Closed() bool

func (*Problab) DeriveSeed added in v0.8.0

func (p *Problab) DeriveSeed(parent []byte, stream core.StreamID) ([]byte, error)

DeriveSeed derives a deterministic child seed using this Problab's Factory.

func (*Problab) EntryById

func (p *Problab) EntryById(id spec.GID) (catalog.Entry, bool)

func (*Problab) EntryByName

func (p *Problab) EntryByName(name string) (catalog.Entry, bool)

func (*Problab) Freeze

func (p *Problab) Freeze()

func (*Problab) IDs

func (p *Problab) IDs() []spec.GID

func (*Problab) NewCore added in v0.5.0

func (p *Problab) NewCore(seed int64) (*core.Core, error)

func (*Problab) NewCoreWithSeedBytes added in v0.8.0

func (p *Problab) NewCoreWithSeedBytes(seed []byte) (*core.Core, error)

func (*Problab) NewCoreWithSeedString added in v0.8.0

func (p *Problab) NewCoreWithSeedString(seed string) (*core.Core, error)

func (*Problab) NewDevSimulator

func (p *Problab) NewDevSimulator(gid spec.GID, seed int64) (*DevSimulator, error)

NewDevSimulator

注意只能由Problab起 只提供給Dev模式使用的模擬器,重點是保持單機台模式所以保持可重現性

func (*Problab) NewMachine

func (p *Problab) NewMachine(id spec.GID, isSim bool) (*Machine, error)

NewMachine 依據 Catalog 內的遊戲 ID 建立一台 Machine。

行為:

  1. 由 Catalog 取得對應的 GameSetting(通常來自 fs.FS 內的 YAML/JSON)。
  2. 由 CoreFactory.GenerateSeed 產生 root seed,再建立 RNG 核心。
  3. 透過 LogicRegistry 依據 GameSetting 內的 LogicKey 建出可執行的遊戲邏輯。

isSim 用於區分「模擬/分析」與「對外服務」的執行模式(例如:某些dto深拷貝行為可能只在 prod 開啟以增加 sim 的性能)。

root seed 不保存在 Machine;可審計重播以受控的 Core Snapshot/Restore 與外部 settlement audit record 為準。

func (*Problab) NewMachineByJSON

func (p *Problab) NewMachineByJSON(raw []byte, seed int64) (*Machine, error)

func (*Problab) NewMachineByJSONWithSeedBytes added in v0.8.0

func (p *Problab) NewMachineByJSONWithSeedBytes(raw []byte, seed []byte) (*Machine, error)

func (*Problab) NewMachineByYAML

func (p *Problab) NewMachineByYAML(raw []byte, seed int64) (*Machine, error)

func (*Problab) NewMachineByYAMLWithSeedBytes added in v0.8.0

func (p *Problab) NewMachineByYAMLWithSeedBytes(raw []byte, seed []byte) (*Machine, error)

func (*Problab) NewMachineWithSeed

func (p *Problab) NewMachineWithSeed(id spec.GID, seed int64, isSim bool) (*Machine, error)

NewMachineWithSeed 與 NewMachine 相同,但由呼叫端指定初始 seed。

使用情境:

  • 可重現的測試:同一份設定 + 同一個 seed,應產生一致的隨機序列(取決於 Core 實作)。

注意:seed 只是「出生入口」。若要在任意時間點完整重現,請使用 Core 的 Snapshot/Restore(以 []byte 交換狀態)。

func (*Problab) NewMachineWithSeedBytes added in v0.8.0

func (p *Problab) NewMachineWithSeedBytes(id spec.GID, seed []byte, isSim bool) (*Machine, error)

NewMachineWithSeedBytes builds a deterministic Machine from opaque seed material. The seed is cloned before it crosses the Factory boundary.

func (*Problab) NewMachineWithSeedString added in v0.8.0

func (p *Problab) NewMachineWithSeedString(id spec.GID, seed string, isSim bool) (*Machine, error)

NewMachineWithSeedString uses the string's unmodified UTF-8 bytes as seed material. Explicitly seeded Machines are deterministic and do not reseed at the production-cycle boundary.

func (*Problab) NewSimulator

func (p *Problab) NewSimulator(id spec.GID) (*Simulator, error)

func (*Problab) NewSimulatorByJSON

func (p *Problab) NewSimulatorByJSON(raw []byte, seed int64) (*Simulator, error)

func (*Problab) NewSimulatorByJSONWithSeedBytes added in v0.8.0

func (p *Problab) NewSimulatorByJSONWithSeedBytes(raw []byte, seed []byte) (*Simulator, error)

func (*Problab) NewSimulatorByYAML

func (p *Problab) NewSimulatorByYAML(raw []byte, seed int64) (*Simulator, error)

func (*Problab) NewSimulatorByYAMLWithSeedBytes added in v0.8.0

func (p *Problab) NewSimulatorByYAMLWithSeedBytes(raw []byte, seed []byte) (*Simulator, error)

func (*Problab) NewSimulatorWithSeed

func (p *Problab) NewSimulatorWithSeed(id spec.GID, seed int64) (*Simulator, error)

func (*Problab) NewSimulatorWithSeedBytes added in v0.8.0

func (p *Problab) NewSimulatorWithSeedBytes(id spec.GID, seed []byte) (*Simulator, error)

func (*Problab) NewSimulatorWithSeedString added in v0.8.0

func (p *Problab) NewSimulatorWithSeedString(id spec.GID, seed string) (*Simulator, error)

func (*Problab) NewUnoptimizedMachineWithSeed added in v0.7.0

func (p *Problab) NewUnoptimizedMachineWithSeed(id spec.GID, seed int64, isSim bool) (*Machine, error)

NewUnoptimizedMachineWithSeed builds a reproducible Machine that executes the configured game logic without selecting a seed from an already-published Optimal Artifact.

Optimizer collection must use this entrypoint. Calling SpinInternal on a normal Machine whose game has optimal_setting.use_optimal=true first restores an artifact seed; a snapshot captured immediately before that call therefore would not be the snapshot that produced the returned outcome. This method clones only the GameSetting value, disables its OptimalSetting, and leaves the frozen catalog untouched. The resulting snapshot-before-spin identity is the exact replay atom consumed by optimizer/v2.

func (*Problab) NewUnoptimizedMachineWithSeedBytes added in v0.8.0

func (p *Problab) NewUnoptimizedMachineWithSeedBytes(id spec.GID, seed []byte, isSim bool) (*Machine, error)

func (*Problab) Register

func (p *Problab) Register(ents ...catalog.Entry) error

func (*Problab) RegisterAll

func (p *Problab) RegisterAll() error

RegisterAll

會掃描 catalog 持有的設定檔來源(fs.FS),把所有可辨識的設定檔(.yaml/.yml/.json)嘗試解析成 *spec.GameSetting,並用設定檔內宣告的 GameID/GameName 產生對應的 catalog.Entry 來批次註冊。

行為特性(重要):

  1. Fail-fast:任何一個檔案讀取/解析/基本檢查失敗,都會立刻回傳 error(不會忽略、也不會繼續掃完)。
  2. 原子性:只有當「全部檔案」都成功解析並通過基本檢查時,才會呼叫 Register(...) 一次性寫入。 因此不會出現只註冊了一半、導致 catalog 處於半完成狀態的情況。
  3. 穩定性:會依檔名排序後再處理,確保行為 determinism(方便重現與除錯)。

注意:

  • RegisterAll 只負責「把設定檔宣告的遊戲資訊放進 Catalog」。

遊戲邏輯(LogicBuilder / LogicRegistry)是否支援該 LogicKey,屬於後續 Problab 組裝/建機台時的責任。

func (*Problab) SnapshotFormat added in v0.6.0

func (p *Problab) SnapshotFormat() string

SnapshotFormat returns the optional identifier used by persisted PRNG snapshots in Optimal Artifacts.

func (*Problab) Summary

func (p *Problab) Summary() ([]catalog.Summary, error)

type ProblabOption added in v0.5.0

type ProblabOption func(*Problab)

ProblabOption 是 Problab 的選項函數類型。

func WithOptimalDir added in v0.6.0

func WithOptimalDir(root string) ProblabOption

WithOptimalDir configures a regular-file Artifact directory. Manifest v1 binary files are opened through the read-only mmap backend on supported Unix platforms. It is mutually exclusive with WithOptimalFS.

func WithOptimalFS added in v0.5.0

func WithOptimalFS(optimalFS fs.FS) ProblabOption

WithOptimalFS 設置可攜式優化文件系統。Manifest v1 會只讀入記憶體一次; legacy Gacha/SeedBank 亦可由此載入。正式環境若要 mmap 請使用 WithOptimalDir。

func WithSeedEntropy added in v0.8.0

func WithSeedEntropy(entropy io.Reader) ProblabOption

WithSeedEntropy configures the entropy source used only when Problab asks the Factory to generate a new root seed. It is not the per-cycle reseed provider; that capability belongs to the concrete PRNG Factory.

type RuntimeHealth added in v0.3.0

type RuntimeHealth struct {
	AtUnixMS    int64      `json:"at_unix_ms"`
	RuntimeOK   bool       `json:"runtime_ok"`
	Reason      string     `json:"reason,omitempty"`
	Overall     string     `json:"overall"`
	ClosedPools []spec.GID `json:"closed_pools,omitempty"`
}

type SeedMaker added in v0.5.0

type SeedMaker struct {
	// contains filtered or unexported fields
}

SeedMaker retains the legacy PCG64 child-seed sequence for source compatibility. New code should use PRNGFactory.DeriveSeed with an explicit StreamID instead.

func NewSeedMaker deprecated added in v0.5.0

func NewSeedMaker(seed int64) *SeedMaker

NewSeedMaker creates the legacy PCG64 child-seed sequence.

Deprecated: new stream partitioning should use PRNGFactory.DeriveSeed with an explicit StreamID domain and ordinal.

func (*SeedMaker) Next added in v0.5.0

func (s *SeedMaker) Next() int64

Next atomically reserves the next legacy ordinal and resolves it through the PCG64 compatibility Factory. The sequence is identical to the former local LCG implementation.

type Simulator

type Simulator struct {
	GameName string   // 遊戲名稱
	GameId   spec.GID // 遊戲名稱enum
	// contains filtered or unexported fields
}

Simulator 用於模擬遊戲行為,可建立多台機台並平行紀錄統計。

func (*Simulator) Sim

func (s *Simulator) Sim(betMode int, round int, showpb bool) (*stats.StatReport, time.Duration, error)

Sim 單線模擬器:以一台機台連續跑指定 round 並回傳統計結果與用時

func (*Simulator) SimMP

func (s *Simulator) SimMP(betMode int, rounds int, mp int, showpb bool) (*stats.StatReport, time.Duration, error)

SimMP 平行執行多個機台,總計 rounds*mp 次 spin,合併統計結果後 回傳統計結果與用時

func (*Simulator) SimPlayers

func (s *Simulator) SimPlayers(mp int, players int, initBets int, betMode int, rounds int, showpb bool) (*stats.StatReport, *stats.EstimatorPlayers, time.Duration, error)

SimPlayers 模擬多個玩家各自帶入初始籌碼的遊戲歷程,並產出機台報表與玩家報表。

type SlotRuntime

type SlotRuntime struct {
	// contains filtered or unexported fields
}

func (*SlotRuntime) Close added in v0.2.0

func (rt *SlotRuntime) Close()

Close transitions the runtime into a closed state. It is safe to call multiple times.

func (*SlotRuntime) Closed added in v0.2.0

func (rt *SlotRuntime) Closed() bool

Closed reports whether the runtime has been closed.

func (*SlotRuntime) ClosedReason

func (rt *SlotRuntime) ClosedReason() string

func (*SlotRuntime) Health added in v0.3.0

func (rt *SlotRuntime) Health() RuntimeHealth

func (*SlotRuntime) PoolMetrics added in v0.3.0

func (rt *SlotRuntime) PoolMetrics(gid spec.GID) (MachinePoolMetrics, bool)

func (*SlotRuntime) Spin

func (rt *SlotRuntime) Spin(ctx context.Context, req *dto.SpinRequest) (dto.SpinResult, error)

Directories

Path Synopsis
cmd
dev command
exp command
opt command
run command
svr command
demo_strategies
Package demo_strategies assembles explicitly selected factories for demo games.
Package demo_strategies assembles explicitly selected factories for demo games.
internal
optimalrt
Package optimalrt owns the immutable runtime representation of optimizer artifacts.
Package optimalrt owns the immutable runtime representation of optimizer artifacts.
v2
Package v2 contains the second-generation Problab math-intent optimizer.
Package v2 contains the second-generation Problab math-intent optimizer.
v2/examples/rgs
Package rgs demonstrates application-owned conversion and Tuner injection.
Package rgs demonstrates application-owned conversion and Tuner injection.
Package playerexp analyzes finite player experiences on a sequential, deterministic, complete-result game.
Package playerexp analyzes finite player experiences on a sequential, deterministic, complete-result game.
cli
Package cli composes playerexp with terminal progress and CSV publication.
Package cli composes playerexp with terminal progress and CSV publication.
strategies
Package strategies provides optional playerexp strategy factories.
Package strategies provides optional playerexp strategy factories.
sdk
buf
gen
layer
Package layer 提供與盤面位置對應的值型別狀態容器。
Package layer 提供與盤面位置對應的值型別狀態容器。
ops
sampler
Package sampler 提供一系列高效能的加權抽樣演算法與工具。
Package sampler 提供一系列高效能的加權抽樣演算法與工具。
tag
Package tag compiles named result predicates into immutable bit assignments.
Package tag compiles named result predicates into immutable bit assignments.
api
api/dev
Package dev 提供 ProbLab 的「內部 Dev Panel」HTTP endpoints。
Package dev 提供 ProbLab 的「內部 Dev Panel」HTTP endpoints。
app
Package app 提供應用程式生命週期管理(App),負責統一啟動與關閉多個 Component。
Package app 提供應用程式生命週期管理(App),負責統一啟動與關閉多個 Component。

Jump to

Keyboard shortcuts

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