Kotlin 68
Let’s do some world-building, with tests. OK, I admit it: no tests yet. Barely made it work.
Just for fun, I think I’ll generate some more reasonable rooms into the actual game that is set up as part of initializing the World. In so doing, I’ll learn more about what to like and what not to like, in the DSL. It won’t surprise me if we need new features.
The main game is set up in the Application. At the moment, it goes like this:
class MainView: View() {
private val world = world {
room("wellhouse") {
desc("You're at wellhouse", "You're in a charming wellhouse")
item("keys")
item("bottle")
item("water")
go("n", "wellhouse")
go("s", "clearing")
go("e", "cows")
}
room("clearing") {
desc("You're in a clearing",
"You're in a charming clearing. There is a fence to the east.")
item("cows")
go("n", "wellhouse")
go("s","clearing")
go("e", "cows") {
it.say("You can't climb the fence!")
false
}
}
room("cows") {
desc("You're in with the cows.", "You're in a pasture with some cows.")
go("w", "wellhouse")
// action("cows") { imp -> say("Leave those cows alone") }
}
I don’t think we have tests relying on this version. I’ll test that by removing most of it. Right, all the tests run. I’ll create a new one. I think I’ll create a separate function for it, outside the World class but inside the World file.
It takes a while, not least because somehow I broke the build entirely, but after a while I have this much world built:
fun makeGameWorld(): World {
val theWorld = world {
room("spring") {
desc("spring", "You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south.")
item("water")
item("bottle")
go("e", "well house")
go("w", "woods")
go("s", "woods toward cave")
action(Phrase("take", "water")) { imp
-> if (inventoryHas("bottle")) {
// addToInventory("bottle of water")
// removeInventory("empty bottle")
contents.add("water")
say("You have filled your bottle with water.")
} else {
imp.say("What would you keep it in?") }
}
}
room("woods") {
desc("woods", "You are in a dark and forbidding wooded area. It's not clear which way to go.")
go("e", "spring")
go("n", "woods")
go("2", "woods")
go("w", "woods")
go("nw", "woods")
go("se", "woods")
}
}
return theWorld
}
I started right off with a hard problem, the water bottle. In the fullness of time, you can take water only if you have an empty bottle, and when you do, your bottle will be known as full. However, there are issues. How will we represent the state of the bottle as full or empty. Ideally, we’d like the game to display something like “you have a bottle of water” or “you have n empty bottle”. But right now, inventory items are just a string … and we only allow two word commands, so “bottle of water” isn’t a legal item name.
But the game does work as the code indicates so far:
Welcome to Tiny Adventure!
You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south..
You find water.
You find bottle.
> take water
What would you keep it in?
You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south.
You find water.
You find bottle.
> take bottle
bottle taken.
You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south.
You find water.
> take water
You have filled your bottle with water.
You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south.
You find water.
> inventory
You have bottle.
You are at a clear water spring. There is a well house to the east, and a wooded area to the west and south.
You find water.
I think we need something more robust than a string for our inventory items, and quite possibly they should have properties that control how they are described.
That seems doable. I’ve learned a bit and given myself something to think about. I’ll push this and go read my book. See you soon!