M pkg/gamemanager/gamemanager.go => pkg/gamemanager/gamemanager.go +33 -5
@@ 50,13 50,17 @@ func (gm *GameManager) StartGame(storyID string) (GameState, error) {
}
// GetStories lists all StoryMetadata for stories tracked by GameManager.
-func (gm *GameManager) GetStories() (map[string]StoryMetadata, error) {
- metadata := make(map[string]StoryMetadata)
- for key, element := range gm.config.Stories {
- metadata[key] = element.Metadata
+func (gm *GameManager) GetStories() []StoryMetadata {
+ metadata := make([]StoryMetadata, len(gm.config.Stories))
+
+ i := 0
+
+ for _, e := range gm.config.Stories {
+ metadata[i] = e.Metadata
+ i++
}
- return metadata, nil
+ return metadata
}
// GetRoomByID finds Room information based on room and story IDs.
@@ 133,3 137,27 @@ func (gm *GameManager) ConstructSpeculativeStates(gameState GameState, currentRo
return speculativeStates, nil
}
+
+// ConstructStartingState generates a starting stateToken for each loaded story.
+func (gm *GameManager) ConstructStartingState(stories []StoryMetadata) ([]SpeculativeState, error) {
+ speculativeStates := make([]SpeculativeState, len(stories))
+
+ for i, s := range stories {
+ startState, startErr := gm.StartGame(s.ID)
+ if startErr != nil {
+ return speculativeStates, fmt.Errorf("could not generate starting state: %w", startErr)
+ }
+
+ startToken, serializeError := gm.SerializeState(startState)
+ if serializeError != nil {
+ return speculativeStates, fmt.Errorf("could not serialize state: %w", serializeError)
+ }
+
+ speculativeStates[i] = SpeculativeState{
+ Description: fmt.Sprintf("%s by %s - %s", s.Name, s.Author, s.Description),
+ StateToken: startToken,
+ }
+ }
+
+ return speculativeStates, nil
+}
M pkg/web/router.go => pkg/web/router.go +1 -2
@@ 28,9 28,8 @@ func StartRouter(gm *gamemanager.GameManager) {
}
g.Handle("/", handleHome(gm))
- g.Handle("/start/:storyid", handleStart(gm))
- g.Handle("/docs*", handleStatic)
g.Handle("/game/:statetoken", handleGame(gm))
+ g.Handle("/docs*", handleStatic)
panic(g.Run("my.crt", "my.key"))
}
M pkg/web/routes.go => pkg/web/routes.go +7 -15
@@ 39,28 39,20 @@ func handleStatic(c gig.Context) error {
func handleHome(gm *gamemanager.GameManager) func(gig.Context) error {
return func(c gig.Context) error {
- stories, _ := gm.GetStories()
+ stories := gm.GetStories()
+
+ startStates, startErr := gm.ConstructStartingState(stories)
+ if startErr != nil {
+ return fmt.Errorf("couldn't load game: %w", startErr)
+ }
return c.Render("gemif:/static/templates/index.gmi.tmpl", map[string]interface{}{
- "Stories": stories,
+ "Stories": startStates,
"Banner": getRandomBanner(),
})
}
}
-func handleStart(gm *gamemanager.GameManager) func(gig.Context) error {
- return func(c gig.Context) error {
- gameState, _ := gm.StartGame(c.Param("storyid"))
- stateToken, serializeErr := gm.SerializeState(gameState)
-
- if serializeErr != nil {
- return fmt.Errorf("could not start game: %w", serializeErr)
- }
-
- return c.NoContent(gig.StatusRedirectTemporary, fmt.Sprintf("/game/%s", stateToken))
- }
-}
-
func handleGame(gm *gamemanager.GameManager) func(gig.Context) error {
return func(c gig.Context) error {
gameState, gameErr := gm.DeserializeState(c.Param("statetoken"))
M static/templates/index.gmi.tmpl => static/templates/index.gmi.tmpl +1 -1
@@ 10,7 10,7 @@ If you want to run your own instance, check out the repo [4]. Once the binary is
Wanna try it out?
{{- range $key, $value := .Stories}}
-=> /start/{{$key}} Start {{$value.Name}} by {{$value.Author}} - {{$value.Description}}
+=> /game/{{$value.StateToken}} {{$value.Description}}
{{- end}}
Or learn more?