Scripts in Book 3 are found in one of four places: embedded in map tiles, associated with a map itself, inside items (whenever you can "Use" an item in your inventory), and a script that an entity runs when it dies. In general, most of the script commands that I've found can be run in any of those places, though some commands only make sense in one context.
Commands can be separated with a semicolon, most often with whitespace around them, so to show a message to the player and play a sound effect, you'd do something like "msg (You hear a noise!) ; sound (sfx_portal)". Note that if you want to get pedantic about this, the semicolon itself isn't even necessary; the parser seems to just ignore them. The semicolons make things much more readable for humans, though, so I recommend you continue to use them.
An example command definition here will be given like so:
asfx (<soundname>) <coords>
The parentheses there are part of the actual command; they should be included if you're using the command. Anything in italics and angle brackets is data that you, as a map editor, should replace with the correct values. Whenever you see <coords> in a command, you'll be using a simple number of the form "YYYXX", though you don't need to zero-pad the number. For instance, the coordinate (34, 125) becomes 12534. The coordinate (5, 28) becomes 2805. Note that the coordinate 0 is considered special, and will cause the effect to happen on the same tile where the script was executed from.
The Book 2 script parser appears to have a fifty-token limit (still the case in Book 3?. A "token" in this case is simply one component of the command. The above asfx example would be three tokens: one for "asfx," one for the sound name, and one for the coordinates. When parentheses are used, it appears that everything inside the parens counts as a single token. So if you're using the msg command to do something like "msg (The gate opens behind you, letting forth a torrent of rats!)", that would only count as two tokens. There is probably a limit to how long a single token can be, and there's also probably a limit to how long a whole script can be, characterwise, but I don't know what those are. Regardless, if you go over fifty tokens in a single script, the game will crash once it tries to execute that script.
Commands which are new in Book 3 will be highlighted in blue. Commands which exist in Book 2 but with a different name or parameters will be highlighted in yellow. Commands which are present in the engine but don't seem to be used by any of the Book 3 scripts will be highlighted in gray. It might be safe to use those commands, but it's possible that they're considered deprecated or something.
Note that even though many of these commands are valid in Books 1, 2, and/or 3, they might behave slightly differently, or have different arguments.
These are commands which should theoretically be valid anywhere.
Each quest has a number in Book 3 - the main quests are numbered 1 through 30, and there are other internal flags the game uses which are technically numbered as quests 100 through 124. Each quest has a "state" number associated with it. To put a quest into the player's Quest book, you'd set the state to 1. It looks like a successfully-completed quest will have a state of 9. Also, quests that are not possible to complete have a state of -1 and ones that were intentionally abandoned have -2.
I've been told that it is possible to use quests higher than 124 (up to at least 20,000, actually) as state variables of your own (for more complex custom mapping, for instance). Use caution when doing so, though, since it's unknown what's happening in the program's memory area when that's being done.
- quest <questnum> <state>
- Set the specified quest to the specified state. State can be given as a negative number with parens, like "(-2)", which is often used when the player abandons quests. (I have also seen where the -2 is not in parens.)
- quest_step <questnum>
- Increments the quest status by one. Used in the Boreheads quest, and for the spiders infesting the Port Kuudad storehouse. Note that you can't use this on "real" quests, only on the "counter" type quests. You can't complete a quest using quest_step.
- Adds all quests to the player's Quest Journal. Note that in Book II, this will cause Eschalon to crash when the player opens his journal; it hasn't yet been tested in Book III. In any case, it's likely a debugging tool.
- List all the quests and their status
These are used to conditionally execute scripts. All of these will abort the execution of the script unless the condition is met. There doesn't appear to be any "else" clause or the like - if the condition isn't met, the script execution will simply stop.
- condition (<text>) (<yes text>) (<no text>)
- Displays a message (on parchment) to the player, with the two given options, and the script will only continue if the user hits "Yes." The last two arguments are usually "Yes" and "No," but it seems they can be just about anything.
- cond_item (<itemname>)
- Script will terminate unless you have the named item
- cond_not_item (<itemname>)
- Script will terminate if you DO have the named item
- cond_quest <questnum> <state>
- Script will only continue if the specified quest is at the specified state
- cond_not_quest <questnum> <state>
- Script will only continue if the given quest is NOT at the specified state
- cond_special <num>
- Special condition, will only continue if some internal criteria is met. Probably not very useful to custom map makers. The special conditions seen in the game:
- Unknown; not used
- 5 pounds puzzle in Baizel's house
- Check for 10 pearls for Arima's quest
- Check for gems in clamshells in Akadai Underworld
- Unknown - used before Erubor's mental conversation when leaving Akadai Underworld
- Check for glass gem in chest in Omentor
- Unknown - used during Karamiklan interaction
- Script will only continue if the player passes a Spot Hidden check (typically this is triggered by a type 13 object, triggered by proximity).
- Script will continue if the script was triggered through a player click.
- Script will only continue if the user isn't at full health (used in healing elixirs).
- Script will only continue if the user isn't at full mana (used in mana potions).
- cond_gold <goldamount>
- Script will only continue if the user has at least the specified gold.
- cond_state <coords> <state>
- Script will only continue if the object at the given coordinates is in the state given. This is typically used to check toggle states. Valid states in the game, used by doors, chests, other containers, and toggle switches (not updated for Book III, may be inaccurate):
- Toggle 1 (upright)
- Toggle 2 (toggled)
- cond_input <password> <fail event>
- Used with user_input to check the word or phrase the user entered. Used for the Snows of May and Master Warren's Crypt puzzles. The only fail event seen in the game is zap.
Interactions with the Player
- user_input (<text>)
- Displays the given text and prompts the user to enter a word or phrase. Only used with cond_input.
- player_face <direction number>
- Makes the player face in a given direction. The only direction used in the game is 4.
- player_bonus <bonus type> <points>
- Gives the player more skill (type=1) or attribute (type=2) points to spend at next level up.
- bonus_att (<attribute>) <points>
- Increases the named attribute by the given number of points.
- give_item (<itemname>)
- Place the named item in the player's inventory
- remove_item (<itemname>)
- Remove the named item from the player's inventory. Safe to call even if the player doesn't have the item, in which case it acts like cond_item and stops execution of the rest of the script.
- Removes all items from the player's inventory, including torches but excluding gold.
- move_player <coords>
- Send the player to the given coordinates, within this map.
- Generate some portal effects, centered on the player square. This is sort of an analogue of "sound (sfx_portal) ; gfx (Port) 0 0" except that it's centered on the player, so you don't need to specify the actual coordinates.
- port_to <coords>
- Send the player to the given coordinates, within this map, with some portal effects. Analagous to "move_player <coords> ; portfx"
- map_port (<mapname>) <coords>
- Send the player to the given coordantes inside 'mapname' Sometimes the parens around mapname are omitted; though it's probably best to use them. When they're omitted, it seems to always be a 'numbered' (outside) map. Note that this doesn't do an implicit portfx, so if you want the portal effects, you should do so explicitly.
- add_gold <n>
- Adds the specified amount of gold directly to the player's inventory
- remove_gold <n>
- Removes the specified amount of gold from the player's inventory
- learn_recipe <recipenum>
- Player learns the given alchemy recipe. Occasionally the recipenum will have parens. recipenum of "99" will give the user all recipes (still true in Book III?)
- gain_xp <xp>
- Give the specified XP. Can include parens around the XP
- Quenches your thirst and fills your waterskins. Note that if you have an object of type 16 (well), you don't need this script.
- Eat <foodval> <drinkval>
- Used on edible food items, but works via other scripts, too. Could implement a cafeteria or something with this.
- Heal <hp> <hidden>
- Heal the given amount of HP; if "hidden" is greater than zero, no message will be shown in the message pane, and the graphical flourishes will be supressed
- Restore <mp>
- Restores the given amount of MP
- Cures ailments. Usually this is associated with a potion, but it doesn't have to be.
- Cures diseases.
- cure_poison <val>
- Cures poison. The value I've always seen is 4, I'm not sure what exactly it means. Usually this is associated with a potion, but it doesn't have to be.
- poison <num>
- Poisons the character for a total of num times, spread out over a number of turns.
- trauma <hp>
- Injures the player by the given HP.
- disease <diseasenum>
- Give the player the given disease (they have a chance to save versus disease resistance, though). Diseases in the game (not updated for Book III yet):
- Troll Fever
- Eye Rot
- player_effect <effect> <levelnum> <duraitionnum>
- Used in potions to grant various effects, though it doesn't have to be tied to an item. The levelnum probably refers to an equivalent spell-casting level, though I don't know that for sure. The effects are as follows, though it seems that not all of these actually work with player_effect:
Some potions that I've noted down:
- Cat's Eyes Brew: EFFECT_CATEYES 3 120
- Haste I: EFFECT_HASTE 3 10
- Haste II: EFFECT_HASTE 3 20
- Haste III: EFFECT_HASTE 3 20
- Ogre Strength: EFFECT_OGRE 3 120
- Invisibility I: EFFECT_INVISIBLE 1 10
- Invisibility II: EFFECT_INVISIBLE 3 20
- Invisibility III: EFFECT_INVISIBLE 6 30
- Keensight: EFFECT_KEENSIGHT 3 120
- Predator Sight: EFFECT_PREDATOR 3 40
- Greater Protection: EFFECT_GREAT_PROT 3 40
- Leatherskin: EFFECT_LEATHERSKIN 3 60
- Nimbleness: EFFECT_NIMBLE 3 120
- Stoneskin: EFFECT_STONESKIN 3 60
- Fortify Mana: EFFECT_FORT_MANA 3 20
- Opens a dialog to allow the player to pay for divine healing. This will deduct gold if they player agrees.
- Opens a dialog to allow the player to pay for divine de-hexing. This will deduct gold if they player agrees.
- This did nothing in Book II. It's unused in Book III and untested as yet.
- Cures all poison, and will attempt to cure diseases. In my limited testing, though, it's possible this isn't actually able to cure disease. Will leave curses untouched.
- rename_item <old name> <new name>
- Renames the given item in the player's inventory.
- rent_room <cost> <coords>
- Used for Inn scripting. Will launch a dialog offering a room for the specified cost. If accepted, the player will wake up at coords.
- teach_skill (<name>) <skillnum>
- Offer to train the player in the specified skill. The player will have to pay the usual fee, and be restricted to the usual Book I training limits. The name argument will just be used to display the name in the initial dialog, and does not have to match any existing NPC.
Interactions with the Map
- npc_interact (<name>)
- Starts a conversation with the named NPC, who must be on the map.
- npc_alignment <entity number> <alignment>
- Changes the alignment of an npc by their entity number. For alignment, 0 is enemy, 1 is friendly, and 2 is friendly-turned-hostile. The 0 vs. 2 distinction is important for the True Healer challenge.
- find_secret <secret number>
- Shows the "you found a secret" message, awards XP, and displays a shower of sparks. Secrets present in the game are 1-30, but you may be able to add more.
- convert_obj <coords> <graphic number>
- Replaces the graphic for the object at given coordinates with a new one.
- blast <coords> <damage>
- Sets off an explosion at the given coordinates.
- alter_light <coords> <level>
- Changes the amount of light at a certain location.
- close_door <coords>
- Closes the given door. Note that there doesn't appear to be an open_door.
- open_port <coords>
- Open the portcullis at the given coordinates
- close_port <coords>
- Closes the given portcullis
- toggle_basedecal <coords>
- Toggle the decal graphic at the given coordinates.
- toggle_port <coords>
- Toggle the given portcullis
- toggle_obj <coords>
- Toggle the existance of a given wall - This will work for basically any graphic. Used, for instance, on the entrance to Lorewitch.
- toggle_zapper <coords>
- Toggles a zapper (electric field) at the given coords
- destroy_obj <coords>
- Completely destroys the given wall - This will work for basically any graphic.
- Spawns a keg in front of the player.
- drop_fusedkeg <coords>
- Spawns a lit keg at the specified coordinates.
- drop_ent <entnum> <coords>
- Drops the given entity at the given coordinates. (Entity Number Lookup)
- remove_npc <entnum>
- Removes all entities with the given ID from the current map. (Entity Number Lookup)
- npc_die <entnum>
- Kills the given entity. (Entity Number Lookup)
- convert_tile <coords> <typenum>
- Converts the given tile to the given object type. Typically this is "0 1", to make hidden cave treasure clickable, after a cond_spot. Note that you can technically change to any type, but make sure that a valid object is in place already for the type you're switching to. The only thing that this changes is the Object Type itself.
- Unknown; is often called immediately after a map_port, but not always. I assume it has something to do with checking for something on the map around where the player just ported to.
- det_keg <coords>
- Detonates the powder keg at the given coordinates. If there's no powder keg there, this has no effect.
- init_trade <entity name>
- Initiates a trade window with the specified NPC. Note that Book III expects the entity's name here, like "Arima". The NPC must be present on the map, and be an actual merchant, otherwise Eschalon will freeze.
- remove_barrier <coords>
- Allow the player to walk through the given coordinates.
- trap <param>
- Plays a sound effect and displays some graphical effects, as if a trap had been sprung, but has no actual effect on the player or environment.
- spell (<spell name>) <level>
- Casts the named spell, at the given level. Unknown spell names will crash Eschalon. I haven't found a way to provide target information for this, so it looks like this command can probably only cast spells which don't require targeting, such as defensive spells. This will deduct the appropriate amount of mana from the player's pool, and can cause the player's MP to go below zero.
- Developer quick-jump to map
- Shows the end-game stats screen
- Reload current map
- Reset quests and NPC flags (developer tool)
- special_event <num>
- Triggers the given special event. These probably aren't really useful to custom map editors, but this is what they are regardless. Events marked with * have hard-coded coordinates, making them difficult to use outside the map where they originally appear.
- * Baptism in fire effect
- * Opens the passage through the trees to Baizel's dungeon
- Unused. Makes mouse cursor disappear
- Unused. Sleep in your own bed from Book II
- Destroys the clam container after taking Crux of Terra. Not sure how it's called, though.
- Runs after talking to Erubor when leaving Akadai underground, unknown effect
- Ulgolek gives you a branch
- *Undead spawn when you take the crystal in Omentor
- *Creates/removes path through the lava in Omentor
- Drink sparkling divinity
- *Explosion when you kill Baelgar in Moonrise Underground
- *Sets the random combination for the Wizardtorium the first time you enter the Oceana Lowlands map
- Shows Karamiklan animation
- Lucky's gambling mini-game
- Daedrotha death trap - 100 damage explosion
- *Karamiklan breathes fire
- *Lets you pick a side in the final battle. Depending on your choice, teleports you to a location and spawns final battle NPCs
- Xaphus killed, show Malkur win graphic if you sided with him
- Malgaelor killed, show Erubor win graphic if you sided with him
- Show dialog between Karamiklan, Malkur, and Erubor. Afterward, main display goes blank.
- gfx (<gfx effect>) <coords> <parameter>
- Launches a fancy graphical effect at the given coordinates. Coords are usually "0" when used in an entity death script, to denote the "current tile." The "parameter" is usually a color number, but can be other things. Here are effects and parameters that I've verified working in Book III. Note that I have not thoroughly tested the parameters for most effects.
- Blast Sparks
- Blood / Gibs
- Chest Open
The number of sparks to display. The typical number used in the game is 4, but I've tried up to 1000.
- Colored Mist / Colored Smoke
6. white (again)
- Divine Light
- Flare / Flare Burst
The number you want to display
- Shower / Sparkles
5. Green and Purple
6. White and Purple
0. Yellow (no discernable change on other numbers)
- Spirit Rise
- msg (<message text>)
- Displays the given text in the message pane
- narrative <narrativenum>
- Displays the given narrative. This is accompanied by a little graphical flourish in the message pane, and a sound effect.
- kill_narrative <narrativenum>
- Tells the game engine not to display the given narrative anymore. Used when a narrative text would no longer be accurate if triggered.
- activate_qt <quicktravel num>
- The player "discovers" the given quicktravel point (this doesn't actually send the player to the quicktravel point, it just makes that point clickable).
- book <booknum>
- Shows book text (just the text, I don't believe it'll actually teach you skills, etc)
- note <booknum>
- Shows note text - like book, above, but with a different graphic. The two commands share the same text numbers.
- Destroys this script (one-time use). Note that if you try to create a one-time use portal, you'll have to call destroy_script before the portal actually takes place, because otherwise the engine will try to destroy a script on the new map, not the old one, and will likely crash.
- Area NPCs may notice you committing a crime
- Allows access to something which would otherwise be considered a crime.
- Used on a corpse-type container, prevents a random chance of getting a disease.
- Plays a "drama" sound. This isn't used at all in Book 2/3, and only once in Book 1 Probably best not to use it. The command does still exist in the engine, though.
- Unknown. This isn't used at all in Book 2/3, and only once in Book 1 (and I can't figure out what it does in Book 1 either). Probably best not to use it. The command does still exist in the engine, though.
- sound (<soundname>)
- Plays the specified sound. The soundfile name might be case-insensitive. I have seen, for instance, both "SFX_Quaff" and "SFX_quaff". Note that the engine will change the pitch somewhat, so consecutive executions may sound slightly different. Note that the soundfiles in question live inside the datapak, so you can't add your own sounds. The soundfiles that I've seen referenced by the game (not updated for Book III):
- asfx (<soundname>) <coords>
- Trigger a sound effect at another location on the map, used to make sounds which appear to happen in the distance.
- display (<graphicfile>)
- Displays the given graphic file (used primarily for roadsigns). Note that the graphic file referenced lives inside the datapak, so you can't add your own graphics.
- Display the in-game time (used in chronometers)
- These do what you'd expect. Note that the screen will not fade back in unless you explicitly call screen_fade_in, so be careful. These seem to replace screen_fade_in/screen_fade_out below, although all four commands are still present in the code.
- These do what you'd expect. Note that the screen will not fade back in unless you explicitly call screen_fade_in, so be careful.
- delay <turns>
- Advances the game time by the specified number of turns. Timed effects will expire, etc.
Usually Only Used in Entity Scripts
These commands are typically found in Entity Death scripts, and often don't make much sense in other contexts. Note that you can call these elsewhere if you want, though.
- drop_gold <n>
- Drops a bag with the specified quantity of gold
- drop_item (<Item Name>) <percent chance>
- Drops the named item with the specified percent chance. Percentage *might* be optional? Set 100 to have it always happen.
- drop_loot <lootlevel>
- Drops loot at the given level. 0 is cheap, 10 is great. Dwarves drop 3, marauders 4, and 11 is a special case for skeletons (mid-level weapons, armor, gold).
Only Used in Item Scripts
These commands are only found in Item scripts, for when you "Use" them, and will typically not work outside of that context.
- convert_item (<new name>)
- Renames the item
- learn_skill <skill>
- Teaches the player the given skill, used in books. This doesn't seem to work properly when used outside of a book - a message will display saying that the player has learned the skill, but the skill value doesn't actually go up, and shows up in red in the character status screen. If anyone can find a way to make it work outside of books, let me know. The skills are:
- Teaches the player the appropriate spell, based on the name of the Item. The item needs to be named "Scroll of Spell Name", or else the game will crash.
- Removes the used item from inventory
- Used on potions to turn the potion into an empty flask
- Used on waterskins
Only Used in Tiles/Squares
These commands are found in square/tile scripts, and don't make much sense outside of that context.
- Toggle this switch's position. (Should only be used when there's a toggle switch.)