Skip to content

Commit

Permalink
WIP: Game Tick Loop
Browse files Browse the repository at this point in the history
Should theoretically run every half second
  • Loading branch information
Muirrum committed Oct 12, 2023
1 parent 8f3818b commit 1a57ec5
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.env
hkgi
/.idea/
77 changes: 74 additions & 3 deletions internal/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package game

import (
"errors"
"fmt"
"github.com/gofiber/fiber/v2/log"
"github.com/hackagotchi/hkgi/internal/state"
"math"
"math/rand"
"time"
Expand Down Expand Up @@ -119,6 +122,24 @@ func MegaboxDrop() map[string]interface{} {
}
}

func LvlFromXp(xp int) int {
// get log_1.3...
log_13 := math.Log(1.3)
lvl := int(math.Log(float64(xp)/10) / log_13)
if lvl < 0 {
lvl = 0
}
return lvl
}

func XpPerYield(xp int) int {
level := LvlFromXp(xp)

// magic numbers!!

return int(math.Floor(900 * (1 - float64(level)/27)))
}

const SECONDS_PER_TICK = 0.5

func RunTick() error {
Expand All @@ -128,7 +149,8 @@ func RunTick() error {
var users []models.Stead
err := db.Select(&users, "SELECT * FROM stead")
if err != nil {
return err
log.Error(err)
continue
}

for _, u := range users {
Expand All @@ -144,21 +166,70 @@ func RunTick() error {
var plants []models.Plant
err = db.Select(&plants, "SELECT * FROM plant WHERE stead_owner=$1", u.Id)
if err != nil {
return err
log.Error(err)
continue
}

tx, err := db.Begin()
if err != nil {
return err
log.Error(err)
continue
}
for _, p := range plants {
if p.Kind == "dirt" {
continue
}
mult := plant_multiplier(p, u)

for mult > 0 {
in_mult := math.Min(mult, 1.0)
xp_per_tick := SECONDS_PER_TICK * 10 // 10 = XP per tick
xppy := XpPerYield(p.Xp)

p.Xp += int(xp_per_tick * in_mult)
xp_since_yield := p.Xp % xppy
if float64(xp_since_yield) <= xp_per_tick {
err := GiveItem(u.Username, map[string]interface{}{fmt.Sprintf("%s_essence", p.Kind): 1})
if err != nil {
log.Error(err)
}

if rand.Float64() < 0.004 {
lvl := LvlFromXp(p.Xp)
if lvl > 5 {
err := GiveItem(u.Username, map[string]interface{}{fmt.Sprintf("%s_bag_t1", p.Kind): 1})
if err != nil {
log.Error(err)
}
}
}
}

}
_, err := tx.Exec("UPDATE plant SET xp=$2 WHERE id=$1", p.Xp, p.Id)
if err != nil {
log.Error(err)
tx.Rollback()
break
}
}
tx.Commit()

}
state.GlobalState.ActivityPrune()

time.Sleep(500 * time.Millisecond)
}

return nil
}

func plant_multiplier(p models.Plant, s models.Stead) float64 {
base_mult := 1.0
for _, status := range s.Ephemeral_statuses["statuses"].([]map[string]interface{}) {
if status["kind"].(string) == p.Kind {
base_mult += status["xp_multiplier"].(float64)
}
}
return base_mult
}
28 changes: 5 additions & 23 deletions internal/handlers/hkgi.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,18 @@ type SerializedPlant struct {
LvlupProg float32
}

func lvlfromxp(xp int) int {
// get log_1.3...
log_13 := math.Log(1.3)
lvl := int(math.Log(float64(xp)/10) / log_13)
if lvl < 0 {
lvl = 0
}
return lvl
}

func getLevelCost(lvl int) int {
return int(math.Floor(10 * math.Pow(1.3, float64(lvl+1))))
}

func getXpRemaining(xp int) int {
lvl := lvlfromxp(xp)
lvl := game.LvlFromXp(xp)

cost := getLevelCost(lvl + 1)

return int(math.Round(float64(cost) - float64(xp)))
}

func xpPerYield(xp int) int {
level := lvlfromxp(xp)

// magic numbers!!

return int(math.Floor(900 * (1 - float64(level)/27)))
}

func GetStead(c *fiber.Ctx) error {
db := database.DB

Expand Down Expand Up @@ -100,16 +82,16 @@ func GetStead(c *fiber.Ctx) error {

if xp > 10 {

xppy := xpPerYield(xp)
xppy := game.XpPerYield(xp)
xp_to_go := getXpRemaining(xp)

// MAGIC: 10 XP/sec
p.TtYield = (float32(xppy) - float32(xp%xppy)) / 10 * 1000 / xp_multiplier
p.YieldProg = float32(xp%xppy) / float32(xppy)
p.TtLevelUp = float32(xp_to_go) / 10 * 1000 / xp_multiplier
p.LvlupProg = float32(xp_to_go) / float32(getLevelCost(lvlfromxp(xp)+1))
p.LvlupProg = float32(xp_to_go) / float32(getLevelCost(game.LvlFromXp(xp)+1))

p.Lvl = lvlfromxp(xp)
p.Lvl = game.LvlFromXp(xp)
} else {
p.TtYield = math.MaxInt
p.YieldProg = 0
Expand Down Expand Up @@ -304,7 +286,7 @@ func Craft(c *fiber.Ctx) error {

recipe := manifest["plant_recipes"].(map[string]interface{})[p.Kind].([]map[string]interface{})[cReq.RecipeIndex]

if !(lvlfromxp(p.Xp) == recipe["xp"].(int)) {
if !(game.LvlFromXp(p.Xp) == recipe["xp"].(int)) {
return &fiber.Error{
Code: fiber.ErrBadRequest.Code,
Message: "come back when you're older, plant!",
Expand Down
1 change: 1 addition & 0 deletions internal/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Craft struct {
}

type Plant struct {
Id int `json:"id"`
Kind string `json:"kind"`
Xp int `json:"xp"`
XpMultiplier float32 `json:"xp_multiplier"`
Expand Down
7 changes: 6 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ func main() {
return c.JSON(&fiber.Map{"data": "Hello from Fiber!"})
})

go game.RunTick()
go func() {
err := game.RunTick()
if err != nil {
log.Fatal(err)
}
}()

app.Listen(":6000")
}

0 comments on commit 1a57ec5

Please sign in to comment.