LavishScript:Designing Scripts

From Lavish Software Wiki
Jump to: navigation, search

Overview

(make sure to read Script Development first)

Artificial Intelligence

The most popular type of script is related to artificial intelligence. For example, automating the actions of a character in a game for the purpose of advancement, with potentially human-like behavior. Characters being controlled automatically by a script or other program are referred to as "Bots" (though the term is also used simply to describe control of multiple characters by a single human).

Ethics

Automation is generally considered "cheating" in most games, though it does not imply having a distinct advantage over a fully human player. For example, First-Person Shooter games are based on how accurately you are able to aim your weapon at the enemy, and how precisely you are able to time the shot -- automated characters in this type of game do have an advantage, because humans are prone to, well, human error, and have slower reaction time than a computer. Role-playing games offer far less of an advantage for automation, because accuracy and precision are not a factor. However, automated characters generally know more about their surroundings without having to process the information visually -- in other words, a bot would simply know where the next monster is, a little bit faster.

Automation in gaming takes its roots in the days of multi-player text games, called Multi-User Dungeons (MUDs). Special programs were made for text games just like special programs are made now for graphical games. Many of these games prohibited automation, partially for the reason that bots sent and received more data than everyone else, and could sometimes slow down the rest of the gamers -- however, savvy players could trick the game and its administrators into thinking it was a human player. Other games simply resigned to their fate, and were designed so that automation would be an accepted and routine part of the game -- usually by increasing the amount of work required to advance, which in turn made it even more desirable to automate play. Modern games that are designed to favor human players over bots make gameplay more dynamic, through adding more quests or other things to do while playing, or increasing the rate at which small portions of content are completed (compare EverQuest, where it takes a large number of levels to stop getting experience from a given monster, to World of Warcraft, which in comparison takes only a few levels to stop getting experience worth automating).

The Basics

Artificial Intelligence in this context is simply a process of determining what actions to take, what conditions are necessary to take them, and exactly how to execute them. For example, on the basic level you may want your character to move, rest, select a target, attack, or gather resources. Each of those may have added detail, such as special attacks and combat healing, requirements for targets, special rest states, and movement speed abilities.

Basic Example

; Artificial Intelligence Base Script
; Note: Most of the Top-Level Objects used in this example are fictional, though Return is built into LavishScript.

function GetState()
{
  if ${Me.Attacking}
  {
    ; We're in combat, so we better get back to attacking
    return "Attack"
  }
  if "${Me.PctHPs}<90"
  {
    ; We're relatively low on hit points, so lets rest up
    return "Rest"
  }
  if ${NearbyResource}
  {
    ; nearby resource, let's gather!
    return "Gather"
  }

  ; We're not in combat, and we're not low on hit points.. find something interesting!
  return "Roam"
} 

function RestState()
{
  do
  {
    waitframe
    ; What do we do while resting?
  }
  while "${Me.PctHPs}<90 && !${Me.UnderAttack}"
  ; The requirements for remaining in rest state
}

function AttackState()
{
  do
  {
    waitframe
    ; What do we do while attacking?
  }
  while "${Me.Attacking}"
  ; The requirements for remaining in attack state

  ; Perform any cleanup -- searching the corpse for items, etc
}

function GatherState()
{
  do
  {
    waitframe
    ; What do we do while gathering?
  }
  while "${NearbyResource} && ${Me.PctHPs}>=90 && !${Me.UnderAttack}"
  ; The requirements for remaining in gathering state
}

function RoamState()
{
  do
  {
    waitframe
    ; What do we do while roaming?
  }
  while "!${NearbyResource} && ${Me.PctHPs}>=90 && !{Me.UnderAttack}"
  ; The requirements for remaining in roaming state
} 

function main()
{
  do
  {
    call GetState
    ; This example calls a function using the return value from GetState, and adding the word "State" to the end
    ; It is also possible to use a switch
    call ${Return}State
  }
  while 1
}

Event Processing

Another popular type of script is an event processor. This type of script simply responds to things that happen, rather than going out and making things happen. Most Fury scripts, for example, will be of this type. For that reason, the example script for this type will be based on Fury.

The Basics

Event Processing in this context is the process of defining events to respond to, and how to respond to them. In Fury, such events are generally lines of text that may appear in a log file (though with further extensions, could equally be a line received from a network connection, or typed somewhere, etc). A response to a line of chat from a friend may simply be to speak it, or a response to information about combat might be to create statistics.

Because LavishScript scripts are actually iterative, events are queued (either internally by an extension, or by the QueueCommand command) and must be executed by the ExecuteQueued command.

Basic Example

function RegisterEvents()
{
 ; Add each event
 AddTrigger MyTrigger "@WHO@ kills YOU."
 AddTrigger YouHit "You hit @WHO@ for @DAMAGE@ point@s@ of damage"   
}

function main()
{
  call RegisterEvents
  do
  {
    if !${QueuedCommands}
      WaitFrame
    else
      ExecuteQueued
  }
  while 1
}

;AddTrigger MyTrigger "@WHO@ kills YOU."
function MyTrigger(string Line, string Who)
{
  Speak -sync You have been killed by ${Who}
}

;AddTrigger YouHit "You hit @WHO@ for @DAMAGE@ point@s@ of damage"
function YouHit(string Line, string Who, int Damage)
{
  ; Note that this function only has 3 parameters. the "s" value from the trigger will be ignored!
  Speak You hit ${Who} for ${Damage} damage
}