Creating continuity¶
In this chapter we’ll create a Game object and put it into a GAME global that will track the overall state of the game. This includes managing an RNG we’ll use to seed the levelgen and each of levels, and tracking the depth of the dungeon the player is currently in.
Getting the message¶
First we’re going to update our Descend message to include the actor that’s descending in it.
--- @class DescendMessage : Message
--- @overload fun(descender: Actor): DescendMessage
local DescendMessage = prism.Object:extend("DescendMessage")
--- @param descender Actor
function DescendMessage:__new(descender)
self.descender = descender
end
return DescendMessage
Let’s also change our Descend action so that we populate the message with the descending actor.
function Descend:perform(level)
level:removeActor(self.owner)
level:yield(prism.messages.Descend(self.owner))
end
Creating the game¶
We’re gonna create a new class Game, and we’re gonna include levelgen at the top.
local levelgen = require "levelgen"
--- @class Game : Object
--- @overload fun(seed: string): Game
local Game = prism.Object:extend("Game")
--- @param seed string
function Game:__new(seed)
self.depth = 0
self.rng = prism.RNG(seed)
end
--- @return string
function Game:getLevelSeed()
return tostring(self.rng:getUniform())
end
--- @param player Actor
--- @return MapBuilder builder
function Game:generateNextFloor(player)
self.depth = self.depth + 1
local genRNG = prism.RNG(self:getLevelSeed())
return levelgen(genRNG, player, 60, 30)
end
return Game
This is going to be where we track everything we need for the overall game in the future. Having one centralized RNG we use for generating seeds for levelgen and levels means that our game will be repeatable given the same seed.
Making it global¶
Head over to main.lua
and right below where we’re loading all our modules we’re going to create our GAME global
and seed our game.
...
prism.loadModule("modules/MyGame")
--- @module "game"
local Game = require("game")
GAME = Game(tostring(os.time()))
Now our GAME
will be accessible all over our codebase.
Modifying the levelstate¶
The first thing we’re going to want to do is remove our require on levelgen.
-local levelgen = require "levelgen"
Then we’re going to change MyGameLevelState
’s constructor.
--- @param display Display
--- @param builder MapBuilder
--- @param seed string
function MyGameLevelState:__new(display, builder, seed)
-- Build the map and instantiate the level with systems
local map, actors = builder:build()
local level = prism.Level(map, actors, {
prism.systems.Senses(),
prism.systems.Sight(),
prism.systems.Fall(),
}, nil, seed)
-- Initialize with the created level and display, the heavy lifting is done by
-- the parent class.
spectrum.LevelState.__new(self, level, display)
end
This sets up our Level with the map we build and the seed we’ll get from our GAME global.
--- @overload fun(display: Display, builder: MapBuilder, seed: string): MyGameLevelState
local MyGameLevelState = spectrum.LevelState:extend "MyGameLevelState"
Let’s change our overload here as well to reflect the new arguments.
if prism.messages.Descend:is(message) then
--- @cast message DescendMessage
self.manager:enter(MyGameLevelState(self.display, GAME:generateNextFloor(message.descender). GAME:))
end
Now we’re going to change our handler for the message to pass the player into the next level.
Moving along¶
We’ve got descending through the levels working, and now we’ve got everything tied together with our Game class. In the next section we’ll work on getting our inventory and a couple items working.