0 votes
by (470 points)
edited by

Thank you very much for your answer. Now I see that I need complex rework. But I have this example of usage:

::StoryInit
<<set $TIME_NAMES = []>>
<<set $TIME_NAMES[0] = "After sunset">>
<<set $TIME_NAMES[1] = "Midnight">>
<<set $TIME_NAMES[2] = "Before the dawn">>
<<set $MAX_TIME = 2>>
<<set $time = 1>>

<<set $ORC = 0>>
<<set $STRENGTH = []>>
<<set $STRENGTH[$ORC] = 5>>
<<set $ENEMY_NAME = []>>
<<set $ENEMY_NAME[$ORC] = "Orc">>

<<set $random_enemy = $ORC>>
<<set $enemy = []>>
<<set $enemy[0] = []>>
<<set $enemy[0][0] = $random_enemy>>
<<set $x = 0>>
<<set $y = 0>> 

::StoryCaption
<<print $TIME_NAMES[$time]>>

::Main
You can see here <<print $ENEMY_NAME[$enemy[$x][$y]]>>.
<<print $ENEMY_NAME[$enemy[$x][$y]]>> has strength <<print $STRENGTH[$enemy[$x][$y]]>>.
[[Next->Start][$time += 1]]

How you can see I need exactly define that "After sunset" related with time = 0. But it's uncomfortable to use push(). And I need two dimensional arrays for coordinates (and I use arrays for fileds too). How is the best way to rework this stuff?

1 Answer

+1 vote
by (159k points)
selected by
 
Best answer

A. When defining variables like your $TIME_NAMES variable whose value never changes during the complete life cycle of the story it is better to define them as setup based variables instead of story variables, that way they don't pad the story's History and Saves.

:: StoryInit
<<set setup.timeNames to ["After sunset", "Midnight", "Before the dawn"]>>
<<set $time to 1>>

:: StoryCaption
<<print setup.timeNames[$time]>>

 

B. Defining items (like a Orc) with properties (like strength) within a story.
There are many existing threads in the Forum covering how to use a Javascript generic object to represent an item with properties, I suggest looking there. One recent one which lightly covered this topic was the Array contains object - problem thread.

C. Parent/Child array structures. (not actually a two/multi dimensional array)
As I stated at the start of this comment, there is nothing wrong with using other methods to create an Array, add elements to an Array, or access the elements of a parent/child array array structure.
The issue in your other Q/A was that you were using a String based Key to access/extent an Array object, and they only support integer based indexes. I suggested using the push() method to stop that practice.

by (470 points)

Thank you very much for your help. 

At first I reworked my game with setup object. Now all constants and functions are in setup.

Second thing about collections and generic object. It's not comfortable for me.( Sorry about this. I will try to make next game with this way, but now I use only numeric arrays. I use only intergers for my IDs (like ORC and it's very comfortable that I have list of all IDs in one place) and I hope that there will no problems.

Only question is: why setup.TIME_NAME[0] = "After sunset" and setup.STRENGTH[setup.ORC] = 10 so bad? I looked at manual about JS arrays, and it's correct syntax. Will I have problem with save and load because of this (if I use only integer IDs)? Or it's for beaty of code?

And last thing. I have something like this:

::StoryInit
<!-- ENEMIES -->
<<set setup.ORC = 0>>
<<set setup.ENEMY_NAME[setup.ORC] = "Orc">>

<!-- LOCATIONS -->
<<set setup.FOREST = 0>>
<<set setup.VILLAGE = 1>>
<<set setup.LOC_NAME[setup.FOREST] = "Forest">>
<<set setup.LOC_NAME[setup.VILLAGE] = "Village">>

<!-- EVENT IDS -->
<<set setup.TALK_WITH_ORC_ABOUT_LIFE_FOREST = 0>>
<<set setup.TALK_WITH_ORC_ABOUT_LIFE_VILLAGE = 1>>
<<set setup.FIGHT_WITH_ORC_FOREST = 2>>
<<set setup.FIGTH_WITH_ORC_VILLAGE = 3>>
<<set setup.TALK_WITH_ORC_ABOUT_WEAPON_FOREST = 4>>

<!-- EVENT TYPES -->
<<set setup.TALK = 0>>
<<set setup.FIGHT = 1>>

<!-- This clild/parent structure is necessary for generation. There are two events in <<set setup.EVENTS[setup.ORC][setup.FOREST][setup.TALK]>> = []>> but in real game it will be more in each array -->
<<set setup.EVENTS = []>>
<<set setup.EVENTS[setup.ORC] = []>>
<<set setup.EVENTS[setup.ORC][setup.FOREST] = []>>
<<set setup.EVENTS[setup.ORC][setup.VILLAGE] = []>>
<<set setup.EVENTS[setup.ORC][setup.FOREST][setup.TALK]>> = []>>
<<set setup.EVENTS[setup.ORC][setup.FOREST][setup.FIGHT]>> = []>>
<<set setup.EVENTS[setup.ORC][setup.VILLAGE][setup.TALK]>> = []>>
<<set setup.EVENTS[setup.ORC][setup.VILLAGE][setup.FIGHT]>> = []>>

<<set setup.EVENT_EXP = []>>
<<set setup.EVENT_TEXT = []>>

<<set setup.EVENTS[setup.ORC][setup.FOREST][setup.TALK].push(setup.TALK_WITH_ORC_ABOUT_LIFE_FOREST)>>
<<set setup.EVENT_EXP[setup.TALK_WITH_ORC_ABOUT_LIFE_FOREST] = 10>>
<<set setup.EVENT_TEXT[setup.TALK_WITH_ORC_ABOUT_LIFE_FOREST] = "You talk with orc in the forest about your life.">>

<<set setup.EVENTS[setup.ORC][setup.VILLAGE][setup.TALK].push(setup.TALK_WITH_ORC_ABOUT_LIFE_VILLAGE)>>
<<set setup.EVENT_EXP[setup.TALK_WITH_ORC_ABOUT_LIFE_VILLAGE] = 10>>
<<set setup.EVENT_TEXT[setup.TALK_WITH_ORC_ABOUT_LIFE_VILLAGE] = "You talk with orc in the village about your life.">>

<<set setup.EVENTS[setup.ORC][setup.FOREST][setup.FIGHT].push(setup.FIGHT_WITH_ORC_FOREST)>>
<<set setup.EVENT_EXP[setup.FIGHT_WITH_ORC_FOREST] = 20>>
<<set setup.EVENT_TEXT[setup.FIGHT_WITH_ORC_FOREST] = "You fight with orc in the forest.">>

<<set setup.EVENTS[setup.ORC][setup.VILLAGE][setup.FIGHT].push(setup.FIGHT_WITH_ORC_VILLAGE)>>
<<set setup.EVENT_EXP[setup.FIGHT_WITH_ORC_VILLAGE] = 20>>
<<set setup.EVENT_TEXT[setup.FIGHT_WITH_ORC_VILLAGE] = "You fight with orc in the village.">>

<<set setup.EVENTS[setup.ORC][setup.FOREST][setup.TALK].push(setup.TALK_WITH_ORC_ABOUT_WEAPON_FOREST)>>
<<set setup.EVENT_EXP[setup.TALK_WITH_ORC_ABOUT_WEAPON_FOREST] = 15>>
<<set setup.EVENT_TEXT[setup.TALK_WITH_ORC_ABOUT_WEAPON_FOREST] = "You talk with orc in the forest about weapon.">>

<<set $curloc = setup.FOREST>>
<<set $random_enemy = setup.ORC>> <!-- It will be generated -->

<<script>> <!-- It is very simplified. There are conditions for avalaible events -->
setup.throw_event = function(enemy, curloc, type) {
	var events = [];
	for (var event = 0; event < setup.EVENTS[enemy][curloc][type].length; event++) {
		events.push(setup.EVENTS[enemy][curloc][type][event]);
	}
	return events.pluck();
}
<</script>>

::Main
You are in <<print setup.LOC_NAME[$curloc]>>
You see <<print setup.ENEMY_NAME[$random_enemy]>>.
<<link "Talk" "Talk">>
	<<set $event = setup.throw_event($random_enemy, $curloc, $setup.TALK)>>
<</link>>
<<link "Fight" "Fight">>
	<<set $event = setup.throw_event($random_enemy, $curloc, $setup.FIGHT)>>
<</link>>

<!-- These two passages I need cause it will be different choices after talk and fight -->
::Talk
<<print setup.EVENT_TEXT[$event]>>
<<set $exp += setup.EVENT_EXP[$event]>>
[[Next->Main]]

::Fight
<<print setup.EVENT_TEXT[$event]>>
<<set $exp += setup.EVENT_EXP[$event]>>
[[Next->Main]]

 Is it normal that I place text in constants but not in passages? I mean all html file of game in RAM in any case so it's not difference for peformance? I will have many events and I heard that Twine will be slowed with more than 500 passages. And it's comfortable for me that all information (text and vars) about event in one place.

by (159k points)

I don't understand your question.

I suggested storing data that doesn't change during the life-cycle of the story in the setup object because it reduces the size of each moment being stored in the History system which in turn reduces the size of of a save.

 

by (470 points)
Oh, okey, I understand.

About my question. Will game be slow if I place text of all events in constants? Maybe 500 or 1000 events with 1000 letters in each. And am I limited with setup object?
...