Numbers in table being read as text?

I have a table that has text in column 1, and real numbers in columns 2 and 3.
However, the numbers are throwing an error because it thinks the numbers are text.

Table of BodyProtection
Armor	Cost		Weight 	 
"leather armor" 	"[cost of leather armor]"		"[weight of leather armor]"
"chain mail" 	"[cost of chain mail]"	 	"[weight of chain mail]"
"plate mail" 	"[cost of plate mail]"		"[weight of plate mail]"
"shield, wooden"	"[cost of wooden shield]"		"[weight of wooden shield]"
"shield, metal" 	"[cost of metal shield]" 		"[weight of metal shield]"

Note that the costs and weights are defined as properties of the armor.

Now I want to modify the cost by a player’s CHR value to get a price charged:

To display armor table:
	let Price be a real number;
	say "[line break][bold type]          A R M O R[line break]";
	say "Armor          Cost          Weight[line break][roman type]";
	repeat through the Table of BodyProtection: 
		now Price is Cost entry * ChrAdj;  [ChrAdj is calculated via To Decide function]
		say "[Price]        "; 
		say "[armor entry] 		[Cost entry]; 	[weight entry][line break]";

This all works great except for the line where the price is calculated.(If I remove it, everything works.) It thinks Cost entry is text. I want to replace [cost entry] with price to get the value I want.

What am I doing wrong?

I think putting something in quotation marks forces it to be text. Plus you’re using a text substitution with the square brackets.

Instead of “[cost of leather armor]” you should just have a number if the base cost is constant. Or if the base cost fluctuates then using a variable like CostOfLeather should work.

You’ll have the same issue with weight if you try to do any math with it.

CostOfLeather is a number that varies. CostOfLeather is initially 6.
CostOfChain is a number that varies. CostOfChain is initially 9.
CostOfPlate is a number that varies. CostOfPlate is initially 15.

Table of BodyProtection
Armor	Cost	Weight 	 
"leather armor" 	CostOfLeather	5
"chain mail" 	CostOfChain 	7
"plate mail" 	CostOfPlate 	10
"shield, wooden"	8	2
"shield, metal" 	12 		3

Also worth noting is that the actual armor pieces in the table are also just text strings and not objects that the player can interact with. Which could be fine depending on the rest of your game.

2 Likes

@CortJstr is right – this is a text, not a number.

cost of leather armor

That’s the number!

1 Like

A table can’t store a reference to a variable, only fixed values.

But in this case what would probably make most sense is to define a kind of value using a table. Then the cost and weight would be actually properties of each item.

Or if you’re defining actual in game objects then just define the cost and weight as actual properties. Using a table doesn’t really help there.

2 Likes

TIL. You just saved me a headache in my WIP because I was in the process of making a table this way.

Well guys,
I tried that and every combination of quotes and brackets. I currently have this (table truncated for convenience and testing):

Table of BodyProtection
Armor	Cost		Weight 	 
"leather armor" 	cost of leather armor		weight of leather armor
"chain mail" 	cost of chain mail	 	weight of chain mail

I get the following parsing errors (with links removed):
In ‘Table of BodyProtection’, I’m reading the text ‘cost of leather armor’ in column 2 (Cost) of row 1, but I don’t know what this means.

In ‘Table of BodyProtection’, I’m reading the text ‘cost of chain mail’ in column 2 (Cost) of row 2, but I don’t know what this means.

And similar error for ‘weight of leather armor’, etc.

Further code used to declare the variables:

[code]
Equipment is a kind of thing.
Equipment has a real number called cost.
Equipment has a real number called weight.
Armor is a kind of equipment.

leather armor is armor. Cost of leather armor is 15.0. Weight of leather armor is 20.0.

chain mail is armor. Cost of chain mail is 75.0. Weight of chain mail is 50.0.

What do I do now? Is it that the table extraction rule can’t make the connection to the variable?

Well, that answers that (no variable in tables, which sucks). I want to show the player the property cost (adjusted) that the player needs to pay to purchase the item. I use a property variable (as shown above) because these variables are used in numerous places throughout the program.

So the conclusion is: I have to copy the constants into the table, which makes me vulnerable to copy and change errors. Right?

General programming wisdom for other languages say: Do not use constants except to define a variable, then if a variable value changes, you only have to change it in one place. I’ve been caught changing constants in the past because sometimes a 5 is not a 5; when I changed one of the many 5’s, one of them stood for a different concept, and broke the code. :frowning:

Let’s see
 in order to declare armors (among other things) and their variables in a single location, while using tables, and avoiding the bugs I describe here (which are probably resolved in the next version of Inform), here’s how I proceed on my end:

Chapter 1 - Armors, Head protections and Shields

Section 1 - Armors - General specifications - (UID 11-50)

An armor is a kind of thing.
An armor is wearable.

An armor has a number called ArmorLevel. [---F039---]
The ArmorLevel of an armor is usually 20.

An armor has a number called CombatSkillModifier. [---F039---]
The CombatSkillModifier of an armor is usually 10.

An armor has a SocialLevel.
The SocialLevel of an armor is usually prosperous.

A solid leather chest armor is a kind of armor. 
The UID of a solid leather chest armor is 11.
solid-leather-chest-armor-description is a text that varies.
solid-leather-chest-armor-description is "This is a standard leather chest armor. [run paragraph on]".

A cushioned leather armor is a kind of armor. 
The UID of a cushioned leather armor is 12.
cushioned-leather-armor-description is a text that varies.
cushioned-leather-armor-description is "This leather armor is lined with padded material, adding an extra layer of cushioning. While it increases comfort, it also enhances the armor's ability to absorb blows, making it suitable for extended wear in combat situations. [run paragraph on]".

[...]

Section 3 - Armors - Completion of kinds

To complete the settings for armor kinds:
	repeat with LocalAsset running through armors:
		let LocalUID be the UID of LocalAsset;
		if (LocalUID < 10000):
			choose a row with an UID of LocalUID in the Table of Assets-Armors;
			now the ArmorLevel of LocalAsset is the ArmorLevel entry;
			now the CombatSkillModifier of LocalAsset is the CombatSkillModifier entry;
			now the printed plural name of LocalAsset is printed plural name entry;
			now the material of LocalAsset is the material entry;
			now the description of LocalAsset is the description entry;
			now the SocialLevel of LocalAsset is the SocialLevel entry;
		
[...]

Section 4 - Table of armors

Table of Assets-Armors[---F039---][---F062---]
UID	ArmorLevel	CombatSkillModifier	printed plural name	material	description	SocialLevel
11	20	2	"solid leather chest armors"	leather	"[solid-leather-chest-armor-description]"	prosperous
12	18	1	"cushioned leather armors"	leather	"[cushioned-leather-armor-description]"	common
13	20	2	"dyed leather armors"	leather	"[dyed-leather-armor-description]"	prosperous

and so on

This way, you can create items without cluttering the properties of your rooms (bug workaround) while still declaring variable values at only one place.

Note that this method is suitable for creating kinds of things, with the intention of later deriving duplicates. A solid leather chest armor is a kind of armor. can be replaced by A solid leather chest armor is an armor. if you want to create unique objects. (I use the 10,000 UID-Unique Identifier limit to distinguish between the two categories and therefore use 2 repeat loops.)

EDIT : of course, you have to invoke the phrase To complete the settings for armor (kinds or not): in a When play begins rule to set up items at the beginning of the game. I set up dozens in my WIP like this :slightly_smiling_face:

EDIT 2 : and also, if a value like the cost of an armor must change, because for example the player is moving from a region to another one, or from a merchant to another one, you could set up several values in the table to reflect this price variation.

1 Like

You don’t need an code table in order to show them to the player, you could just loop through the armour items. You could even present a table to the player, without having a code table. Or if you fill a code table before immediately showing the player then you don’t need to worry about it having out of date data.

1 Like

That’s absolutely true. For the display part, there’s no need to structure the information in a table for the player to view it in an organized form, which allows you to work directly with the values and sum them up.

1 Like

Though I’d argue that defining the armor via a table is the most convenient way to do it.

Lab is a room.

An armor is a kind of thing. An armor is wearable.

Some armor in Lab is defined by the Table of BodyProtection.

The description of an armor is "A piece of armor weighing [ArmorWeight].".

Table of BodyProtection
Armor    BaseCost    ArmorWeight
leather armor    15.0    20.0
chain mail    75.0    50.0

You could add whatever other attributes you want via other columns, like an armor class. Your “to display” function would work with just the minor tweaks the column names.

There’s nothing wrong with calling the columns cost and weight, you just have to be sure you won’t use those same terms for anything else so personally I use more specific column headings to protect me from myself.

1 Like

It is theoretically true, and the manual advises us to proceed this way to create (unique, not duplicates of a kind) objects and their values using tables. Unfortunately, this function is bugged. To demonstrate this, we can observe the appearance of unsolicited properties in each of the rooms:

>showme lab
Lab - room
    yourself - person
    leather armor - armor
    chain mail - armor
lighted, visited; singular-named, proper-named
description: none
printed name: "Lab"
printed plural name: none
indefinite article: none
list grouping key: none
BaseCost: 0.0
ArmorWeight: 0.0

To address this problem, to my knowledge, we have three options: wait for the new official stable version of Inform; compile the current development version if the IDE is not required; or proceed as follows (example to adapt):

Table of weapons
UID	printed plural name	description	HPDamageMax	material	height	width
12001	"imperial swords"	"[imperial-sword-description]"	40	steel	0.6 hmeter	0.15 wmeter

To create weapons:
	repeat with LocalAsset running through things which are weapons:
		let LocalUID be the UID of LocalAsset;
		choose a row with an UID of LocalUID in the Table of weapons;
		now the printed plural name of LocalAsset is printed plural name entry;
		now the description-addon of LocalAsset is the description entry;
		now the HPDamageMax of LocalAsset is the HPDamageMax entry;
		now the material of LocalAsset is the material entry;
		now the height of LocalAsset is the height entry;
		now the width of LocalAsset is the width entry;
	
When play begins:
	create weapons;

An imperial sword is a unique-weapon.
The UID of an imperial sword is 12001.
imperial-sword-description is a texts that varies.
imperial-sword-description is "Your imperial sword, [...]"
1 Like

I want the player to see all the equipment available for sale (adjusted by the player’s Charisma value), and each item’s weight. I still think defining a constant in a single place is a good idea, so I’ll define the constants in the table and use a phrase to link to the constant when I use it. The table the player sees is not exactly the same table in which I define the constants.