diff --git a/README.md b/README.md index 51efb0e..ca4b613 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ A bucket of game state. ### Stat -An arbitrary variable (or function, if it's calculated) tagged with some stuff to make it easier to display to the player. +An arbitrary variable (or function, if it's calculated) tagged with some stuff to make it easier to display to the player. Stats can be extracted automatically (see "Stat Extraction" below). ### StatsCollection @@ -57,3 +57,26 @@ There are some special errors that Rules can use to "communicate with" the rule ### Messages For now, strings but inconvenient. Intended to provide forwards compatibility when we eventually include some way to format text, where all the stuff written for "it's just a string" would break if not for having this extra type in the way to wrap it where we can stay compatible with "it's just a string" mode. + +## Stat Extraction +The function `ExtractStats` creates a stats list automatically by searching through a struct's fields and methods. The following things are recognized as stats: + +* any method with a name like `StatFoo` or `HiddenStatFoo` (the latter are marked as invisible stats, which show up only in debug mode with the implementation in BasicStatsPane) +* any exported field with a type that is already a `Stat`; the `Stored[T]` and `Hidden[T]` generic types are containers for this +* any exported field tagged with `cardsim:"stat"` + * or `cardsim:"hidden"` for hidden stats. `"hiddenstat"` also works. + * you can use `"round2"` to round to two decimal places -- you can use any integer here, not just 2. works with both `float` types. + * `"hiddenround3"` (or any other number) creates a hidden rounded stat. + * To change the display name of a stat, use a separate tag phrase in addition to the stat tag, `cardsim_name:"name"`. + * For example: `cardsim:"stat" cardsim_name:"Stat Display Name"` creates a visible stat that shows up as "Stat Display Name". + * `cardsim:"hiddenround1" cardsim_name:"Hidden Rounded Stat"` creates an invisible stat that shows up, rounded to one decimal place, as "Hidden Rounded Stat". + +Stat extraction can implement most or all of your type's `Stats` method for you: + +``` +func (e *ExampleType) Stats() []cardsim.Stat { + return cardsim.ExtractStats(e) +} +``` + +ExtractStats puts methods first (lexicographically), then fields (in the order they appear). You can use `cardsim.SortStats` to instead put visible stats before hidden stats, alphabetized (case-insensitive). diff --git a/smoketest/cards.go b/smoketest/cards.go index 8c99745..217ec6b 100644 --- a/smoketest/cards.go +++ b/smoketest/cards.go @@ -85,7 +85,7 @@ func (i inverseDivision) OptionText(p *player) (cardsim.Message, error) { func (i inverseDivision) Enact(p *player) (cardsim.Message, error) { if p.Stats.Number.Value == 0 { - return nil, errors.New("you can't divide by zero!") + return nil, errors.New("you can't divide by zero") } p.Stats.Number.Value = int(i) / p.Stats.Number.Value return cardsim.MsgStr("Inverse divided."), nil