Please help me understand and implement relations

Hi. Me again … I’m having a hard time grokking how to define and implement relations. How to use them. (EDIT: Yes, I’ve read that chapter in the manual. Several times. Looked at the examples. Still having a tough time wrapping my head around the concept and how to use it)
So in this game I’m making (for IF Comp … hopefully) the player pans and mines for gold. I originally “just made it work,” but in a pretty hacky fashion that ended up causing some weird problems later. So I decided to completely re-write both the actions and the objects.
I’d had several different explicit objects for gold: Powder, flakes, grains, and nuggets. And the panning/mining actions had to … I dunno … it was just inelegant and hacky and problem causing.
So I decided to implement gold as a single kind (ProtoGold), with those four types as a property (is that the right term?)
Rooms have a property set as well: None, poor, okay, or rich.
So now I’m trying to set up a relation such that the player can pan/mine for gold, and “the system” works out which type of gold the player gets depending on location.
To help me work this out, I made a concept map (see below) and have now added the relation as such:

Gold Quality relates various rooms to ProtoGold.

But now I don’t know how to USE it to determine which type the player gets.
EDIT: D’OH … I neglected to mention the desired behavior re: locations to gold type.
None = no gold
Poor = powder and flakes
Okay = flakes and grains
Rich = grains and nuggets
Also, currently the game won’t even compile because I broke how the actions work and gold is given to the player. So I need to get this working before I can continue.

Here’s the concept map:

Are you asking for input on design, Inform implementation, or both?

In terms of design, I’d think you’d just create a set of tables relating the qualities to a distribution of the different types, based on the overall gold economy you’re trying to create. E.g., if you pan in a Poor location, you get 1d6 grains, a 50% chance of 1d4 powders, a 25% chance of a flake, and a 1% chance of a nugget, vs. in a Rich location where you’d get 1d6 powders, 1d4 flakes plus a 50% chance of an additional 2d4 flakes, and a 33% chance of 1d4 nuggets, with a 4 leading to a re-roll (fun to have the opportunity to strike a really rich vein!)

You’d need to tune based on what the player will do with all this gold, and whether or not you the different kinds of gold will feed into some other system (refining, sale…) – could be that you want the quantities to be lower or higher, or create a shallower or steeper differential between the different quality locations depending on how important you want it to be to find the best locations.

In terms of implementation, I think this can all be done relatively easily with a table and the appropriate carry out actions – I will flag that making ProtoGold a kind, and then the form of the gold a property of instances of the kind, seems more likely to lead to awkwardness than making nuggets, flakes, etc. kinds of things with “golden” as a property.

Both I guess? :woozy_face:

hmm … Via tables. Interesting … Hadn’t really considered that. I’ll hafta think about what you’ve said here.

I mean, there might be a way to do it via relations too – I’m pretty much a novice with Inform so there are probably clever things I’m missing. But I think you’re basically looking for a way to look up a Quality and get quantities of four different sorts of gold, and seems like a table is the most compact way to do that (and would be relatively easy to tune since you can see and change all the different outcomes at a glance)

1 Like

Yeah. I’m a novice too. Still working my way thru the manual as I write. Read it in bed and reference it while writing the game LOL
I see what you’re saying about tables. Makes some sense I guess. hmmm

Is ProtoGold a kind of thing/object or a kind of value? Do you track individual gold nuggets, etc., or just record the quantity of gold the player has?

Is the intention of the Gold Quality relation that it maps rooms to each of the kinds of gold that might be found there? In that case, you could do something like:

A gold form is a kind of value. The gold forms are gold powder, gold flakes, gold grains, and gold nuggets.

Gold Quality relates various rooms to various gold forms.
The verb to produce means the gold quality relation.

The river produces gold powder. The river produces gold flakes.
The mine produces gold grains. The mine produces gold nuggets.

Then you can use phrases like if the location produces a gold form to check whether any gold is found here, a random gold form produced by the location, or repeat with X running through gold forms produced by the mine.

However, you can’t make a relation involving kinds, so this will need some adjustment if you want gold nuggets to be a kind of thing and each nugget to be tracked separately.

2 Likes

Rather than a relation, I’d probably just make it a property of a room.

A gold production rate is a kind of value.
The gold production rates are none, poor, okay, rich.
A room has a gold production rate called bounty.

The bounty of the river is okay.
The bounty of the mine is rich.
3 Likes

Three things need to happen: The player receives inventory item(s), the player receives N oz. of gold, and the room description changes.
Updated chart:

There is, in general, three different ways to represent counted objects.

You can have 100 (say) individual flake objects that you create at the start and either distribute to the appropriate rooms, or keep in an out-of-game “warehouse” until they’re needed to give to the player. This represents the most that the player can ever have at any time – either because the world “runs dry” once they have it or for some other reason. This avoids needing to dynamically create more flakes if you “run out” (which is possible with Glulx, but takes more effort).

Or you can do something similar, but instead make (say) 500 gold objects that get a property set on them to make them be described as flakes or nuggets etc, as needed. This is more fiddly to set up all the conditional descriptions but means that you can “borrow” one type to make another if your distribution is lopsided for some reason.

A completely different approach is to only ever make one (or two) flake objects – one is on the ground in any room that happens to need it, and the other is in the inventory once they have at least one (this might be optional, depending on the interactions required). The specific count of how much they have is stored as a numeric property on the object, rather than duplicating the object itself. This requires a bit more work to get actions to behave (especially when splitting stacks), but if there’s only a small number of actions that deal with gathering gold and making use of it (presumably for purchases) then this can be quite feasible.

2 Likes

@Dannii 's idea inspired me.
So I started a new project and mocked up a set of rooms, with each room being of the Gold Chamber kind of room, which defaults to being empty, and contains the descriptions for all four possible states of a room (empty, poor, okay, rich). Then, when creating new rooms, I can just say which state the room is and it gets those properties, or defaults.
Then I wrote a “digging” action (and digging it with, which redirects to digging) which, based upon the room state, increases the score. Each time digging is done in a room, its state goes down by one.
It was super simple to mock up. And once the Kind of room is defined, it’s easy to add in the rooms and define actions that depend on the state(s) of the rooms.

And yeah @mirality that last idea. Once the player has one of each type (powder, flake, grains, nugget(s)) that’s it. No need for more. The amount of gold the player has is simply defined in ounces. But then there’s no gold object on the ground in any rooms. It’s not something you see and know until you try digging.

The mock up is working great. So I think (hope) it won’t be very difficult to graft it into the game code already written. And it’s simpler than the hack that’s in there LOL.
Going with a kind of room, not object.

1 Like

Yeah. I think that’s going to work.
Updated chart:

I did this in The Baker of Shireton. There were 50 actual coins available in the game world that the player would collect, but whenever they interacted with coins when fewer than 25 were available off-stage, a rule would force the player to insert them into a locked strongbox, recycle the physical coins to the supply off-stage, and increase a variable that represented how many they had collected in total.

1 Like

After many many hours I’ve mostly got this working now. The biggest remaining problems are how the gold is listed in the inventory and that for some reason, gold is out of scope at the beginning of the game. If, on the first turn, the player says: pan for gold, you’re told it’s not there and SHOWME says it’s not in scope. But if the player types, say: pan in river, then suddenly the player has (if successful) some gold, and the gold is in scope.

By default, only objects in the current room and inventory are in scope. So if nothing in the inventory is understood as gold then the parser won’t recognise that as a valid object.

You can either explicitly put the gold objects in scope, always start the player holding the gold objects but with a value of zero, or write the grammar for actions like pan for gold such that it recognises the literal word gold and not an object, so it doesn’t matter if it’s not in scope.

Personally, I would probably just put the objects in the inventory at the start, unless there’s some compelling reason that they’re not supposed to know of the existence of some form of gold until they’ve found at least one.

You could optionally also choose to hide it from the inventory listing if the value is zero – though it’s not unreasonable to display it regardless.

1 Like

How did you define the command for panning? Unless your game allows panning for different things, then something like Understand "pan for gold" as panning. should work without requiring any gold to be in scope.

2 Likes