Beginner s&box Tutorials: Chapter 2 - Creating your First Gamemode

This tutorial will guide you through creating your first gamemode in s&box. We will set up our addon, write our first lines of code, and run our newly created gamemode in s&box.

Beginner s&box Tutorials: Chapter 2 - Creating your First Gamemode

This tutorial will guide you through creating your first gamemode in s&box. We will set up our addon, write our first lines of code, and run our newly created gamemode in s&box.

Setting up the Addon

To begin writing your gamemode, you first need to set up your addon. This is an easy process, and you'll get familiar with it in no time.

First, go to your s&box installation folder (Manage -> Browse local files on s&box in Steam). Open the addons folder, and create a new folder. Make the name of this folder the name of your addon, gamemode, etc.

I'm naming my addon "MyFirstGame"

Click into this new folder. In this folder, you need to create a .addon file so that s&box recognizes your gamemode. For now, all you need in this file is the following block of text:

{
	"sharedassets": "*.*"
}
Copy and paste this into your .addon

Next, create a folder titled code. Within this code folder, create an empty file named MyFirstGame.cs, or something similarly titled. The .cs file extension stands for C# (C-Sharp), which is the language we use to write s&box gamemodes. Now that we have our .addon file and our first C# file, we can reboot s&box. Upon launch, s&box will regenerate the s&box.sln file.

The structure of your gamemode folder

Writing Your First Lines of Code

After you have regenerated your solution file and re-opened it, your Visual Studio should be open and contain your brand new addon in the Solution Explorer as shown below!

MyFirstGame should appear in the Solution Explorer

Double click MyFirstGame.cs to open the file in the editor window. You can copy and paste the following code into your editor, or you can type it yourself line-by-line. Either way, we will discuss what each line does.

using Sandbox;

namespace MyFirstGame
{
	public partial class MyFirstGame : Game
	{
		public MyFirstGame()
		{
			Log.Info( "Hello from MyFirstGame!" );
		}

	}
}

As a quick tip, you can hit Ctrl+S to save the file you're currently looking at in Visual Studio. Once you have this code in your editor and saved, you can open the game in s&box. Do this by hitting the little "save" icon in the top left of the menu, clicking MyFirstGame, clicking New Game, and then clicking Start The Game.

The "save" icon allows you to browse your local gamemodes.

Since s&box requires every game loads up with a map, you will likely have to download Facepunch's gm_construct, which happens automatically for you. If everything went well, the download will complete and you will be in game!

Currently, our code doesn't really do much. You won't have a character to move around with, or a camera to pan. You'll be stuck staring at a blank image. Before we continue adding more code, however, there are a few tools you can check out.

The Developer Console

If you have played Garry's Mod (or any Source game) at all, you are probably familiar with the developer console. The console is enabled by default in s&box, and you can press the tilda key ~ to open it.

The Developer Console within s&box

This console has significantly more content to look at than any other console you've probably seen. First is the actual console, which is directly below the game window. Here you can see info messages, error logs, and more from your game. If you look closely, you can actually see the message we logged in our code Hello from MyFirstGame! in the console.

Most of this information is not super useful to us right now, but there is one command every s&box developer should know - the devcam. Typing the command devcam into the console and pressing enter will put you in a noclip free-flying camera mode. Then, you can press tilda ~ again to close the console. Feel free to explore the map with this camera if you wish.

Back to the Code

Once you feel comfortable with the console and the devcam, open your editor back up and take a look at MyFirstGame.cs again. What good is the code we just wrote without knowing what it does? Feel free to skip this if you are already experienced with C#.

using Sandbox; - The using directive lets you any types defined within the Sandbox namespace without prefacing the type with Sandbox.Example. We use this a couple of lines down by referencing Sandbox.Game as just Game.

namespace MyFirstGame - A namespace declares a scope which should contain a logical set of related objects. Anything within the curly braces {} after a namespace is included in the namespace.

public partial class MyFirstGame : Game - A class defines a type of object. public means MyFirstGame can be referenced outside of its own class. partial is required since we are extending the Sandbox Game class. The : Game is what is causing the extension to happen. The extension will allow us to override methods from the base Game class. We will be using one soon called ClientJoined.

public MyFirstGame() - The constructor for the class. In object-oriented programming, most classes will have a constructor, which is sort of an instruction on how to set the object up when it is first created. To learn more about object-oriented programming (OOP), we recommend reading the Microsoft Docs.

Log.Info( "Hello from MyFirstGame!" ); - This is the simplest method to log information to the console in s&box. You will probably use this often!

Creating your first Player

We have a game running, but how do we get a character to move around? In your editor, create a new class named MyFirstPlayer.cs. You can do this by right clicking your MyFirstGame solution, and mouse down to Add -> Class (shortcut Shift+Alt+C).

Adding MyFirstPlayer.cs to our Solution

Your editor should open with MyFirstPlayer.cs, and it might be automatically populated with some lines of code.

Most IDEs will automatically generate some code for you upon creating a new class

You can remove all of the using directives at the top, since we won't need them right now. Add the using Sandbox; directive. Then, change internal class MyFirstPlayer to public partial class MyFirstPlayer : Player. Just like MyFirstGame, MyFirstPlayer will extend a base class that Sandbox provides for us to make setting up our game easier. Once you make those changes, you should end up with something like this:

using Sandbox;

namespace MyFirstGame
{
	public partial class MyFirstPlayer : Player
	{
    	
	}
}

Now we are ready to start writing the code for MyFirstPlayer.

To create a player, we need to spawn it into the game. The base Player class has lots of methods you can override, and we need one called Respawn().

public override void Respawn()
{
	base.Respawn()
}

base.Respawn() will call the base Player class's Respawn() method. This abstracts a lot of information away from us - we don't need to worry about a lot of nitty gritty details, because the base method already accomplishes it.

Even though the base method accomplishes lots for us, there are still lots of little things we need to take care of. First, we need to set the model of our player. Inside the Respawn() method, we can add SetModel( "models/citizen/citizen.vmdl" );. This will set our player's model to the default s&box citizen model.

Next, we need to set our Controller. Add the line Controller = new WalkController();. If you're wondering where the Controller property came from, it exists in the base Player class. Since we have extended Player, we can access it from the MyFirstPlayer class with ease.

Similarly, we need an Animator and a Camera.

Animator = new StandardPlayerAnimator();
Camera = new ThirdPersonCamera();

At this point, you should have enough to have a functioning player to move around! But first, we need to initialize MyFirstPlayer in our game class. In your editor, switch back to MyFirstGame.cs.

Every time somebody joins a s&box game, their client is passed to your gamemode. This client is needed to interact with the players of your gamemode. In MyFirstGame.cs, add a new overridden method called ClientJoined.

public override void ClientJoined( Client client )
{
	base.ClientJoined( client );
}

Just like Respawn() from Player, this method has a base method that we need to call. The client contains plenty of information about the user who joined your game. We are interested in one particular property in client called Pawn, which you can reference by typing client.Pawn. Let's create an instance of MyFirstPlayer and assign it to client.Pawn, so that our client has an entity attached to it. Then, we'll call the Respawn() method of player, which will create the player entity and spawn it into the game.

public override void ClientJoined( Client client )
{
    base.ClientJoined( client );

    MyFirstPlayer player = new MyFirstPlayer();
    client.Pawn = player;

    player.Respawn();
}

With all of this code written, we can finally start our game again. If you're still in game, you'll have to leave and re-join to get these changes. Start your game, and you'll notice you're in control of a citizen!

My Citizen is hanging out in gm_construct!

What's Next?

Feel free to play around with your code. As a challenge, try changing the ThirdPersonCamera to a FirstPersonCamera, and see how it affects your game. If you've completed the tutorial, you can move on to Chapter 3 (WIP).

Feedback

If you have feedback, questions, or comments, feel free to shoot me a DM on twitter @sboxcommunity! We will try to keep these tutorials as up-to-date as possible. s&box is still in early access and constantly evolving, meaning things can become outdated very quickly.