Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

params.gno

3.84 Kb · 112 lines
  1package game
  2
  3import "chain"
  4
  5// param is one tunable number of the game, with the bounds an admin has to
  6// stay within.
  7type param struct {
  8	key   string
  9	value int64
 10	min   int64
 11	max   int64
 12	doc   string
 13}
 14
 15// paramLeaderboardSize is the one param the realm itself consumes. Every
 16// other param is only stored here and applied by the game server.
 17const paramLeaderboardSize = "leaderboard_size"
 18
 19// defaultParams returns the registry with its default values. The order is
 20// the display order, in StateJSON as well as in Render.
 21func defaultParams() []*param {
 22	return []*param{
 23		{"plane_speed", 70, 20, 300, "cruise speed, m/s"},
 24		{"boost_speed", 130, 20, 600, "speed while boosting, m/s"},
 25		{"boost_capacity_ms", 4000, 0, 60000, "how long a full boost tank lasts, 0 disables boost"},
 26		{"boost_recharge_ms", 10000, 100, 600000, "time to refill an empty tank while not boosting"},
 27		{"turn_rate", 80, 20, 360, "pitch and turn responsiveness, deg/s"},
 28		{"plane_health", 100, 1, 1000, "hit points"},
 29		{"fire_cooldown_ms", 160, 50, 5000, "minimum time between shots"},
 30		{"bullet_speed", 400, 100, 2000, "m/s"},
 31		{"bullet_ttl_ms", 1500, 100, 10000, "bullet lifetime"},
 32		{"bullet_damage", 20, 1, 1000, "hit points removed per bullet"},
 33		{"respawn_ms", 3000, 0, 60000, "delay before a destroyed plane respawns"},
 34		{"balloon_respawn_ms", 6000, 0, 600000, "delay before a popped balloon comes back"},
 35		{paramLeaderboardSize, 10, 1, 100, "entries a leaderboard keeps, on-chain and on the server"},
 36		{"max_players", 64, 1, 1000, "server capacity"},
 37		{"bot_max", 2, 0, 16, "bots flying with a lone pilot, 0 for no bots"},
 38		{"bot_off_players", 5, 1, 64, "from this many pilots there are no bots"},
 39		{"bot_aim_error", 8, 0, 45, "how far a bot's shot can stray from its aim, degrees"},
 40		{"bot_fire_interval_ms", 900, 100, 10000, "minimum time between a bot's shots"},
 41	}
 42}
 43
 44// findParam returns the param registered under key, or nil. The registry is
 45// a dozen entries, a linear scan is cheaper than any index.
 46func findParam(key string) *param {
 47	for _, p := range params {
 48		if p.key == key {
 49			return p
 50		}
 51	}
 52	return nil
 53}
 54
 55// SetParam changes a game parameter. Admin only.
 56//
 57// The key must exist and the value must be within the bounds of that key,
 58// see Render("params"). Lowering leaderboard_size truncates the kill
 59// leaderboard right away. Raising it does not bring back the lines that were
 60// dropped: the list fills up again as kills come in.
 61func SetParam(cur realm, key string, value int64) {
 62	assertAdmin(0, cur)
 63	p := findParam(key)
 64	if p == nil {
 65		panic(errUnknownParam)
 66	}
 67	if value < p.min || value > p.max {
 68		panic("gnofly: " + key + " must be between " + itoa(p.min) + " and " + itoa(p.max))
 69	}
 70	p.value = value
 71	if key == paramLeaderboardSize {
 72		trimRankings()
 73	}
 74	bump()
 75	chain.Emit("ParamSet", "key", key, "value", itoa(value))
 76}
 77
 78// SetParamBounds changes the range SetParam accepts for a key. Owner only.
 79//
 80// The bounds are the guard rail between the owner and the admins: admins tune
 81// values within them, the owner decides how far tuning may go. The current
 82// value has to fit the new bounds, so that the registry never holds a value
 83// SetParam would refuse.
 84func SetParamBounds(cur realm, key string, min, max int64) {
 85	assertOwner(0, cur)
 86	p := findParam(key)
 87	if p == nil {
 88		panic(errUnknownParam)
 89	}
 90	if min < 0 || min > max {
 91		panic(errInvalidBounds)
 92	}
 93	// An empty leaderboard has no last line to compare a new total with.
 94	if key == paramLeaderboardSize && min < 1 {
 95		panic(errLeaderboardMin)
 96	}
 97	if p.value < min || p.value > max {
 98		panic(errValueOutOfBounds)
 99	}
100	p.min, p.max = min, max
101	bump()
102	chain.Emit("ParamBoundsSet", "key", key, "min", itoa(min), "max", itoa(max))
103}
104
105// Param returns the value of a game parameter. It panics on an unknown key.
106func Param(key string) int64 {
107	p := findParam(key)
108	if p == nil {
109		panic(errUnknownParam)
110	}
111	return p.value
112}