What you have been writing so far were top-level statements. And while they are just fine for learning and writing simple scripts, for more complex behaviour it is easier to use classes.
If you want to have scripts for multiple heroes, every hero has to have a class named after him that inherits
from the base class AutomaticHero.
Warning
If you start using classes, you have to stop using top-level statements. Currently you should also edit the .csproj file in %LOCALAPPDATA%\GrindFest\GrindFest\Scripts\ and remove all the automatic <Using> tags that were added by the game.
Classes
A class is a template that describes the behaviour of a an object.
using GrindFest; // Classes are usually grouped into namespaces. Most of the game classes, including AutomaticHero, are in the GrindFest namespace
// This is a class that represents all behaviour of your bot.
// It's name is MyHero (name of your hero) and it inherits its behaviour from the parent/base class AutomaticHero (inheritance will be covered later)
class MyHero : AutomaticHero
{
// Curly brackets define the boundaries of your class.
// All the code that describes your bot’s behavior will go inside these braces.
}
Warning
Name of your hero class must match the name of your hero in game
Methods
Class contains methods. Methods are blocks of code that perform a specific task.
Let's start editing your bot and make it say "Hello World" when it starts.
Method declaration
First you need to declare a method. Give it a name, specify the return type and parameters (if any) and write the code inside the method body in the curly braces.
Note: This method doesn't need to return any value, so the return type is
void
. It doesn't take any parameters, so the parentheses are empty. This will be covered later
Method call
When you want to execute the code inside the method, you need to call it using it's name followed by parentheses. If the method takes any parameters, you need to pass them inside the parentheses as argument1, argument2, ...
.
Every statement (line of code) in C# ends with a semicolon ;
.
class MyHero : GrindFest.AutomaticHero // Instead of `using namespace` we can use fully qualified names that include the namespace
{
// This is a declaration of a method called Start, a sequence of code. A code from inside the game will call this when the bot is started. Any code you put here will be executed when the bot starts (when you change the script bot restarts)
void Start()
{
// block of code surrounded by curly brackets, everything in here belongs to this method, the code runs sequentially from top to bottom
Say("Hello World"); // Call a method Say, this method is implemented in the base class AutomaticHero, we are passing a text string as an argument
}
}
When you call method that has parameters declared like Say(string) you need to pass the argument inside the parentheses. In this case we are passing a string "Hello World". A string is a sequence of characters enclosed in double quotes, used to represent text.
Note: You can call the method Say even though you haven't declared it, because it's declared in the base class AutomaticHero.
class MyHero : AutomaticHero
{
// This is an Update method and it's called by the game all the time (Approximately 60 times per second). Whatever you put here, the bot will be doing it.
void Update()
{
if (IsBotting) // The Update method is called even if you pause the bot, this check is to make sure the bot is running. I'll be skipping it in tutorials if not relevant.
{
FollowCursorAndAttack(); // Makes your hero follow your mouse cursor and attack nearby enemies
}
}
}
In this method we are checking a where IsBotting is true.
Note: When you click the
Play
button or pressF5
the game will set IsBotting to true.
If you don't include the if
statement, the bot will follow your cursor even when you pause it.
We can also invert the condition, so we don't have to have everything nested inside the if
statement. In this case the return
statement is used to stop the execution of the method and return to the caller.
class MyHero : AutomaticHero
{
void Update()
{
if (!IsBotting) // If the bot is not running, we don't want to do anything
{
return;
}
//TODO: add your bot logic here
}
}
Note:The Update method has a return type
void
so you don't need to write what value you want to return in the return statement.
Recursion
If you wish to crash your game you can use recursion.
Recursion means your method calls itself - recursively. Since there will be no pause between the calls and no exit conditon the game will freeze forever calling the method again and again.
class MyHero : AutomaticHero
{
void Crash()
{
Crash(); // This will call the Crash method again and again until the game crashes
}
void Start()
{
Crash();
}
}
Static Classes
In some cases you don't need to have multiple instances of some classes, these classes usually represent some sort of utility or helper classes.
In this game we have a static class Hero that represents your current hero. You can call methods on this class without creating an instance of it by using the class name Hero
.
See also
- AutomaticHero class api reference
Glossary
- Class: A blueprint for creating objects. It defines properties and methods that the objects created from the class will have. Microsoft C# Fundamentals on Classes
- Method: A block of code that performs a specific task. Methods are defined within a class and can be called to execute the code they contain. Microsoft C# Programming Guide on Methods.