krisajenkins / transcodegame

A game!
4 stars 1 forks source link

"Use" bugs #1

Open adituv opened 8 years ago

adituv commented 8 years ago
adituv commented 8 years ago

I think the first of these needs more discussion before I can fix it: how do we handle it? My initial idea is to allow a "use item on its own" interaction, which happens when we use an item in the world directly. This is easily implementable by using the distinction between Interact and InteractAt. However, this would currently be an unused control.

If we do implement that, I'd also like to restrict "Use" on two items so the first always has to be an inventory item.

krisajenkins commented 8 years ago

I think we can fix this by taking the inventory out of the world. Instead, we store a list of objects as Dict Object Location where Location is:

type Location | InWorld Position | InInventory | None

Then:

  1. Uniqueness of objects is automatic.
  2. Removing items from the world is easy.
  3. Interactive with world items is as easy as interacting with inventory items.
  4. InteractAt need only worry about the floor and walls, and we could remove if it's painful because they're only there for lines of dialogue.
  5. Checking that at least one used item is in the inventory is easy.
  6. canStandOn becomes a little more difficult. One solution is to put blocks in the world "underneath" immovable objects, and then allow you to stand on things you can pick up.

What do you think?

adituv commented 8 years ago

It's certainly a workable method for a single-room game. For multiple chapters or rooms, as I was hoping to do later, it might become a bit unwieldy, however. I'd rather keep the inventory as a separate list entirely for that extension, which unfortunately does lose the guaranteed uniqueness.

I'd like to tweak the idea a little, and store a record of a few properties for objects instead, including an "enabled" property, so we for example disable the shed and enable the wheelbarrow rather than changing the tile or object. Whether an object has collisions could then also be a record field, but this is now treading rather close to OOP.

(Edit: also, as Object isn't comparable, we would need a separate ObjectId from some comparable type to use this method.)

As a quick sketch:

type Object = Object { friendlyName : String -- A human-readable name in the current language
                     , location : Position
                     , enabled : Bool
                     }

type alias Inventory = List ObjectId
-- Alternatively:
-- type alias Inventory = Set ObjectId

type alias WorldRoom = Dict ObjectId WorldObject