you can simply copy and paste any code posted into a game file (and save), then switch to the GUI~Editor mode, to see how it is done through the editor (GUI), though it is a bit time-consuming and the GUI~Editor doesn't intuitively match up well with how it is syntaxed~formated (done) in code, lol. It's a lot of work learning to match up coding with the editor's style... at least it was for me... (see example directly below)
for example:
in code:as tag creation:
<object name="orc">
-> <inherit name="editor_object" />
-> <attr name="dead" type="boolean">false</attr>
</object>
or in scripting creation:
orc.dead = false
and then to change it (via scripting):
orc.dead = true
to change it back (via scripting):
orc.dead = false
whereas, in GUI~Editor:to create it via an attribute of an object:
"orc" (Object) -> Attributes (Tab) -> Attributes -> Add ->
Attribute Name: dead
Attribute Type: boolean
Attribute Value: false
to create it (via scripting):
Run as script -> Add a script -> Variables -> Set a variable or attribute -> orc.dead=false
to change it:
Run as script -> Add a script -> ??? (whatever it's category, 'Objects', I think) -> SetObjectFlagOn -> (set it up)
to change it back:
Run as script -> Add a script -> ??? (whatever it's category, 'Objects', I think) -> SetObjectFlagOff -> (set it up)
---------
I'm more than willing to guide with with using the GUI~Editor, if you don't want to work with code, but the main problem is time, as it takes more work~time to write out explanations and step by step instructions in using the GUI~Editor, vs just pasting in code, lol, and unfortunately, I am busy with real life, so if you don't mind to wait for when I got the time, I'd gladly help you with doing things in the GUI~Editor, when I got the time for doing it.
until then, (or until others are able to help you), the main sources of GUI~Editor help (with nice pictures of it too) are:
the tutorial (
http://quest5.net/wiki/Tutorial )
the wiki guides (
http://quest5.net/wiki/How_to )
and some of the libraries (
viewforum.php?f=18 )
though, it is a bit more limited, compared to the amount of coding help that exists.
----------
oh indeed, learning a new language is not easy, as you're used to the old format, and when you learn the new language, then you'll have a new problem of mxing up the two languages, not remembering what syntax~format goes with which language, lol.
however, quest's language is really noobie-friendly, so you should be able to pick it up quickly in-of-itself, though it does take time to adjust to any new language.
http://quest5.net/wiki/Category:ASLX_Elementshttp://quest5.net/wiki/ASLX_Elementsthe various elements:
Objects, Exits, Verbs, Commands, Timers, Turnscripts, Functions, Game, Object Type ( it's shortened in the tags to just: <type name="blah">attributes</type> ) (grouping~inheritance), Templates, Libraries, Walkthroughs, etc
basically, you do this (ignoring the optional attributes):
(can be written horizontally or vertically)
The Elements:
<object name="blah">attributes</object>
<verb name="blah">scripting</verb>
<command name="blah">scripting</command>
<type name="blah">attributes</type> // <type> is short for: Object Type
<turnscript name="blah">scripting</turnscript>
<timer name="blah">scripting</timer>
<function name="blah">scripting</function>
<exit name="blah">attributes</exit>
<attr name="blah" type="blah">values</attr>
attr = Attribute
The Attributes:
int = integer
boolean = specifically in terms of quest's coding usage, just "true~false" flags
coding conceptuality (no "flag" element~attribute actually exists, you create effect by~via scripting): 'flags' are binary: 0~1 and more expansively, dualism: 5~10, on~off, yes~no, in~out, up~down, hot~cold, red~blue, etc ~ aka: only two options~settings
(these are just custom ones, using my own labeling system~structure, for examples)
<object name="HK">
<attr name="parent" type="object">room</attr>
<attr name="gender_string" type="string">male</attr>
<attr name="strength_integer" type="int">0</attr>
<attr name="dead_boolean" type="boolean">false</attr>
<attr name="damage_double" type="double">156.84</attr>
<attr name="favorite_colors_string_list" type="simplestringlist">black;red</attr>
<attr name="clothes_object_list" type="objectlist">shirt;socks;shoes;pants</attr>
<attr name="fight_script" type="script"><![CDATA[
if (HK.dead_boolean=true) {
msg ("He's already dead, silly!")
} else if (HK.dead_boolean=false) {
player.hp = player.hp - HK.damage_double
msg ("HK attacked you.")
if (player.hp <= 0) {
finish // this ends the game
} else {
HK.hp = HK.hp - player.damage_double
msg ("You attack HK, ... (but you can NEVER kill him, muwahaha!)")
if (HK.hp <= 0) {
HK.dead_boolean=true
}
}
}
]]></attr>
// etc attribute types
</object>
-----------
there's a few ways to do different outcomes:
1. firsttime~otherwise script (
http://quest5.net/wiki/Firsttime and
http://quest5.net/wiki/Otherwise )
2. the built-in boolean attribute: "visited" (only for "type: room" Objects though, I think...)
3. basic "if coding" or just "coding": your own flag effect of scripting, a simple example below:
game.count = 5
if (game.count = 5) {
-> msg ("hi")
-> game.count = 10
} else if (game.count = 10) {
-> msg ("bye")
-> game.count = 5
}
the "Value" (5,10,red,blue, etc) doesn't matter, if you only have two outcomes, than only two options~settings are needed, for another example:
game.count = red
if (game.count = "red") {
-> msg ("hi")
-> game.count = "blue"
} else if (game.count = "blue") {
-> msg ("bye")
-> game.count = "red"
}
the built-in boolean attribute:
room.visited = true
if (room.visited = false) {
-> msg ("hi")
-> room.visited = true
} else if (room.visited = true) {
-> msg ("bye")
-> room.visisted = false
}
using the "firsttime~otherwise" script~function (it probably does and uses the same thing~method as above for you ~ it probably changes~resets the built-in "visited" boolean attribute between "true" and "false"):
firsttime {
-> msg ("hi")
} otherwise {
-> msg ("bye")
}
----------
the simpliest method is using the "firsttime~otherwise" script:
<object name="room">
<inherit name="editor_room" />
<inherit name="editor_object" />
<attr name="look at" type="script"> // I believe this built in script attribute, is the 'room description', but I'm not exactly sure how the GUI~Editor works, as there's also the "onenterroom" or "onenterroomfirsttime" (a possible option too if it exists ~ can't remember off top of my head) and etc 'room description' scripts...
firsttime {
msg ("a long room description of all the scenery and etc stuff")
} otherwise {
msg ("a shorter description, without all the fluff")
}
</attr>
</object>
-----------
ken wrote:A thought strikes me. If I want all rooms to have both a long (first time) and short (re-visit) description, is it possible to alter the template for a room to have two boxes for descriptions, then alter the default room description script to display the appropriate one, so I don't have to add the code (as described in cybernetsurfer7's solution) to every room description? I'm assuming this would be via a "template" or is that wrong? I'd also need to alter the default action of the "LOOK" verb somehow?
"Templates" are more for responses (messages ~ msg), if you want to change the default or error_exception response, or it also makes it easier to translate the game into another (speaking, not programming lol) language (of font used), as they can be used as a 'called upon' (like you do with functions) or "invoke" (for scripts), but for a response (msg), instead.
however, what you want, is achieved by changing the scripting (script or function) itself of the built-in "room description" or "look at" scripts~functions, which can be done by:
an example:
Filter -> Show Library Objects~Elements (whatever it is called) (so it is toggled "on" obviously)
(Verb) eat (greyed font~text) -> copy -> alter it as you want
you can see all the built-in stuff by just clicking on "filter" to bring up the toggle button "show library objects~elements" within the GUI~Editor:
New Game's "Tree of Stuff":
Objects
Game
Verbs
Commands
Room
Player
Functions
Timers
Walkthrough
Advanced
Included Libraries
English.aslx
Core.aslx
Templates
Dynamic Templates
Object Types
Javascript
Filter -> Show Library Objects~elements (whatever it is)
***** AND *****
you can then alter~change these default built-in stuff by click on it (the light grey font'ed things) in the "tree of stuff" (so that it is highlighted) allowing you to see the coding of it and also to change it (via the "change" button in the upper right),
THOUGH do understand that these are global changes to the built-in stuff, which the underlying coding uses too, so be careful, as you may not want the global effect or it might cause the underlying code to not be able to work with your changes to these built-in things.
HOWEVER, by doing it this way, the quest engine is protected, as you're copying it, making changes to the copy, and thus not messing up the actual quest engine of coding (though your specific game file may not work because of your changes ~ but you don't have to re-download the quest program~software)
-------------------
quest itself uses a default of two libraries (codings):
Core.aslx
English.aslx
(see the ' <include ref="blah" /> ' below)
<!-- New Game Code -->
<asl version="540">
<include ref="English.aslx"/>
<include ref="Core.aslx"/>
<game name="Testing Game Stuff">
<gameid>d67ec73f-f879-4911-9d88-c02ea527c534</gameid>
<version>1.0</version>
<firstpublished>2014</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>
which makes it easy to add more libraries (codings) too:
<asl version="540">
<include ref="English.aslx"/>
<include ref="Core.aslx"/>
<include ref="Chase's Wearables Library File.aslx" />
<include ref="Pixie's Spell Library File.aslx" />
// etc library files
<game name="Testing Game Stuff">
<gameid>d67ec73f-f879-4911-9d88-c02ea527c534</gameid>
<version>1.0</version>
<firstpublished>2014</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>
heck, let's completely re-customize quest, lol:
<asl version="540">
<include ref="English.aslx"/>
<include ref="HK's New Core (haha maybe 50 years later I'd have this coding ability lol) Library File.aslx"/>
// it's architecture is completely different, HK's own creation... my long long long term programming goal... lol
</asl>
so literally, libraries are "patches", "expansion packs", or even "the quest source~core code itself" of code (adds, changes, or removes code) that can be added to quest. Alex made quest extremely (easily) customizable for those good at programming.
libraries can be extremly simple, adding a single object to a game, or it can literally be a totally new source~engine code, lol.
I believe in the programming world, libraries are like your "data files" ???
aka:
actor(PCs~NPCs)_data_file
physics_data_file
media_data_file
game_mechanics_data_file
objects(NON-PCs~NON-NPCs)_data_file
scripts~events~flags_data_file
and etc data files
which are combined (or called upon) from a single: global data file or *.exe game file
----------------
here's an example of a library, and also how works and what are "templates":
Pixie's Spell Library:
<?xml version="1.0"?>
<library>
<!--
This library adds a basic magic system to quest. It allows for three types of spells:
nonattackspell: Instant effect
lastingspell: An on-going spell. These last until another spell is cast
attackspell: Instant effect, attacking anything of the "monster" type that is not dead
Attack spells must be of an element, and eight are already set up. Monsters
can be assigned to elements too; they will be immune to that element, but take
four-fold damage from the opposed element.
A "Magic" tab is added to the editor to make setting up spells and monsters as easy as possible.
-->
<!--
Adding new elements involves a bit of effort. This system requires that elements are added in pairs or opposites,
such as fire and frost.
1. Create a new type for both elements, named [elemem]_type
2. In the data section, the object element_struct needs both elements added to both "elements" and
"opposedelements", and for the latter you need to put them in both ways around (look at existing entries)
3. You need to add both elements to the tab, both for "monster" and for "attackspell". Again, see existing
entries.
-->
<!-- =================================================== -->
<!-- Templates -->
<!--
Using templates makes it easier to convert to other languages, but also for other users to word it how they want it.
When templates are in the library that uses them (as here) the way to change the language is to
modify the template in the library, so really the only benefit is that all the text is together here.
Also modify the default responses in the verbs!
-->
<template name="Learn">learn</template>
<template name="Cast">cast</template>
<template name="LookDead">Oh, and it is dead.</template>
<template name="SpellAlreadyKnown">Er, you already know that one!</template>
<template name="SpellNotKnown">Er, you don't know that one!</template>
<template name="NoMonstersPresent">No monsters present</template>
<dynamictemplate name="SpellEnds"><![CDATA["The <i>" + GetDisplayAlias(object) + "</i> spell ends."]]></dynamictemplate>
<dynamictemplate name="SpellCast"><![CDATA["You cast <i>" + GetDisplayAlias(object) + "</i>."]]></dynamictemplate>
<dynamictemplate name="SpellLearnt"><![CDATA["In a process that seems at once unfathomable, and yet familiar, the spell fades away, and you realise you are now able to cast the <i>" + GetDisplayAlias(object) + "</i> spell."]]></dynamictemplate>
<!-- =================================================== -->
<!-- Verbs -->
<verb>
<property>learn</property>
<pattern>[Learn]</pattern>
<defaultexpression>"You can't learn " + object.article + "."</defaultexpression>
</verb>
<verb>
<property>cast</property>
<pattern>[Cast]</pattern>
<defaultexpression>"You can't cast " + object.article + "."</defaultexpression>
</verb>
<!-- =================================================== -->
<!-- Functions -->
<!--
Handles an attack on the given monster, using the given spell.
Monster loses hit points according to the spell's powerrating.
If they share an element, then no damage, if elements are opposed, damage is multplied by 4
Handles monsters with no elements too, but spell must have an element set.
-->
<function name="SpellAttackMonster" parameters="monster, spell"><![CDATA[
element = GetElement (monster)
handled = False
if (not element = Null) {
if (DoesInherit (spell, element + "_type")) {
msg ("... " + monster.ignoreselement)
handled = True
}
if (DoesInherit (spell, StringDictionaryItem (element_struct.opposedelements, element) + "_type")) {
monster.hitpoints = monster.hitpoints - 4 * spell.powerrating
handled = True
if (monster.hitpoints > 0) {
msg ("... " + monster.hurtbyelement)
}
else {
msg ("... " + monster.deathbyelement)
Death (monster)
}
}
}
if (not handled) {
monster.hitpoints = monster.hitpoints - spell.powerrating
if (monster.hitpoints > 0) {
msg ("... " + monster.hurt)
}
else {
msg ("... " + monster.death)
Death (monster)
}
}
]]></function>
<!--
Call this when a spell is cast, to ensure any on-going spells
are terminated.
-->
<function name="CancelSpell"><![CDATA[
if (HasObject (player, "currentspell")) {
spell = player.currentspell
msg (DynamicTemplate("SpellEnds", spell))
player.currentspell = null
if (HasScript (spell, "terminate")) {
do (spell, "terminate")
}
}
]]></function>
<!--
Call this when a monster dies for some housekeeping.
-->
<function name="Death" parameters="monster"><![CDATA[
monster.alias = monster.alias + " (dead)"
if (HasString (monster, "lookwhendead")) {
monster.look = monster.lookwhendead
}
else {
monster.look = monster.look + " [LookDead]"
}
monster.dead = True
]]></function>
<!--
Returns as a string the name of this object's element (or null).
-->
<function name="GetElement" parameters="obj" type="string"><![CDATA[
result = Null
foreach (element, element_struct.elements) {
type = element + "_type"
if (DoesInherit (obj, type)) {
result = element
}
}
return (result)
]]></function>
<!--
Describes casting
-->
<function name="DescribeCast" parameters="spell"><![CDATA[
if (HasString (spell, "description")) {
msg (DynamicTemplate("SpellCast", spell) + " " + spell.description)
}
else {
msg (DynamicTemplate("SpellCast", spell))
}
]]></function>
<!-- =================================================== -->
<!-- Object types -->
<type name="spell">
<inventoryverbs type="list">Learn</inventoryverbs>
<displayverbs type="list">Learn</displayverbs>
<drop type="boolean">false</drop>
<take type="boolean">false</take>
<usedefaultprefix type="boolean">false</usedefaultprefix>
<learn type="script"><![CDATA[
if (not this.parent = player) {
this.parent = player
this.inventoryverbs = Split ("Cast", " ")
msg (DynamicTemplate("SpellLearnt", this))
}
else {
msg ("[SpellAlreadyKnown]")
}
]]></learn>
</type>
<type name="attackspell">
<inherit name="spell"/>
<cast type="script"><![CDATA[
// Check the player has the spell
// If so iterate through all objects in the room
// Apply attack to those with the monster type that are not dead
if (this.parent = player) {
DescribeCast (this)
flag = False
foreach (obj, ScopeVisibleNotHeld ()) {
if (DoesInherit (obj, "monster") and not GetBoolean (obj, "dead")) {
SpellAttackMonster (obj, this)
flag = True
}
}
if (not flag) {
msg ("... [NoMonstersPresent]")
}
CancelSpell ()
}
else {
msg ("[SpellNotKnown]")
}
]]></cast>
</type>
<type name="nonattackspell">
<inherit name="spell"/>
<cast type="script"><![CDATA[
if (this.parent = player) {
DescribeCast (this)
do (this, "spelleffect")
CancelSpell ()
}
else {
msg ("[SpellNotKnown]")
}
]]></cast>
</type>
<type name="lastingspell">
<inherit name="spell"/>
<cast type="script"><![CDATA[
if (this.parent = player) {
DescribeCast (this)
do (this, "spelleffect")
CancelSpell ()
player.currentspell = this
player.status = this.status
}
else {
msg ("[SpellNotKnown]")
}
]]></cast>
</type>
<type name="fire_type">
</type>
<type name="frost_type">
</type>
<type name="storm_type">
</type>
<type name="earthmight_type">
</type>
<type name="shadow_type">
</type>
<type name="rainbow_type">
</type>
<type name="divine_type">
</type>
<type name="necrotic_type">
</type>
<type name="monster">
</type>
<!-- =================================================== -->
<!-- Data -->
<!--
This is a data store for elements (I call it a "struct" after the keyword in the C programming language)
If you add more elements to the name, you need to add them to both lists as well as creating a new type.
Note that your new type must end "_type", but that must not be included on these lists.
-->
<object name="element_struct">
<elements type="list">fire; frost; storm; earthmight; shadow; rainbow; divine; necrotic</elements>
<opposedelements type="stringdictionary">fire = frost;frost = fire;storm = earthmight;earthmight = storm;shadow = rainbow;rainbow = shadow;necrotic = divine;divine=necrotic</opposedelements>
</object>
<!-- =================================================== -->
<!-- Tabs -->
<tab>
<parent>_ObjectEditor</parent>
<caption>Magic</caption>
<mustnotinherit>editor_room; defaultplayer</mustnotinherit>
<control>
<controltype>dropdowntypes</controltype>
<caption>Spell type</caption>
<types>*=None; nonattackspell=Non-attack spell; lastingspell=Lasting spell; attackspell=Attack spell; monster=Monster</types>
<width>150</width>
</control>
<control>
<controltype>title</controltype>
<caption>Non-Attack Spell</caption>
<mustinherit>nonattackspell</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description (optional)</caption>
<attribute>description</attribute>
<mustinherit>nonattackspell</mustinherit>
</control>
<control>
<controltype>script</controltype>
<caption>Spell effect</caption>
<attribute>spelleffect</attribute>
<mustinherit>nonattackspell</mustinherit>
</control>
<control>
<controltype>title</controltype>
<caption>Lasting Spell</caption>
<mustinherit>lastingspell</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description (optional)</caption>
<attribute>description</attribute>
<mustinherit>lastingspell</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Status when active</caption>
<attribute>status</attribute>
<mustinherit>lastingspell</mustinherit>
</control>
<control>
<controltype>script</controltype>
<caption>Spell effect</caption>
<attribute>spelleffect</attribute>
<mustinherit>lastingspell</mustinherit>
</control>
<control>
<controltype>script</controltype>
<caption>Cacel spell effect</caption>
<attribute>terminate</attribute>
<mustinherit>lastingspell</mustinherit>
</control>
<control>
<controltype>title</controltype>
<caption>Attack Spell</caption>
<mustinherit>attackspell</mustinherit>
</control>
<control>
<controltype>number</controltype>
<caption>Power of attack (1-10)</caption>
<attribute>powerrating</attribute>
<width>100</width>
<mustinherit>attackspell</mustinherit>
<minimum>0</minimum>
<maximum>10</maximum>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description (optional)</caption>
<attribute>description</attribute>
<mustinherit>attackspell</mustinherit>
</control>
<control>
<controltype>dropdowntypes</controltype>
<caption>Element</caption>
<types>*=None; fire_type=Fire; frost_type=Frost; storm_type=Storm; earthmight_type=Earthmight; shadow_type=Shadow; rainbow_type=Rainbow; necrotic_type=Necrotic; divine_type=Divine</types>
<width>150</width>
<mustinherit>attackspell</mustinherit>
</control>
<control>
<controltype>title</controltype>
<caption>Monster</caption>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>dropdowntypes</controltype>
<caption>Element</caption>
<types>*=None; fire_type=Fire; frost_type=Frost; storm_type=Storm; earthmight_type=Earthmight; shadow_type=Shadow; rainbow_type=Rainbow; necrotic_type=Necrotic; divine_type=Divine</types>
<width>150</width>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>number</controltype>
<caption>Hit points</caption>
<attribute>hitpoints</attribute>
<width>100</width>
<mustinherit>monster</mustinherit>
<minimum>0</minimum>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description on injury</caption>
<attribute>hurt</attribute>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description on death</caption>
<attribute>death</attribute>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description on injury by opposed element</caption>
<attribute>hurtbyelement</attribute>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description on death by opposed element</caption>
<attribute>deathbyelement</attribute>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Description on ignore</caption>
<attribute>ignoreselement</attribute>
<mustinherit>monster</mustinherit>
</control>
<control>
<controltype>textbox</controltype>
<caption>Look (when dead)</caption>
<attribute>lookwhendead</attribute>
<mustinherit>monster</mustinherit>
</control>
</tab>
</library>