Difference between revisions of "Creating a GameMode"

From Serious Sam's Bogus Detour
Jump to: navigation, search
(Versus)
Line 1: Line 1:
{{NewBuild|The minimal example using <code>BaseGameMode</code> described here will cause null reference exceptions if <code>GetHUD()</code> returns null.}}
 
 
 
Gamemodes define rules about what should happen on a level. They are set in a level file. Typically when making a gamemode, you'll want to inherit the class from either <code>BaseGameMode</code>, <code>VersusGameMode</code>, or <code>TeamVersusGameMode</code>. Or, if you're just adding something very simple to an existing gamemode, you can also inherit from <code>Campaign</code>, <code>Survival</code>, <code>Deathmatch</code>, etc.
 
Gamemodes define rules about what should happen on a level. They are set in a level file. Typically when making a gamemode, you'll want to inherit the class from either <code>BaseGameMode</code>, <code>VersusGameMode</code>, or <code>TeamVersusGameMode</code>. Or, if you're just adding something very simple to an existing gamemode, you can also inherit from <code>Campaign</code>, <code>Survival</code>, <code>Deathmatch</code>, etc.
  

Revision as of 16:07, 27 June 2017

Gamemodes define rules about what should happen on a level. They are set in a level file. Typically when making a gamemode, you'll want to inherit the class from either BaseGameMode, VersusGameMode, or TeamVersusGameMode. Or, if you're just adding something very simple to an existing gamemode, you can also inherit from Campaign, Survival, Deathmatch, etc.

These scripts are typically saved in your scenario in a scripts/gamemodes folder.

Base

There are several ways you can set up the base of a gamemode.

Minimal gamemode

The most minimal gamemode you can make is this:

[GameMode]
class BasicGamemode : BaseGameMode
{
	BasicGamemode(Scene@ scene)
	{
		super(scene);
	}
}

Note the [GameMode] preprocessor that describes our BasicGamemode class. This tells the engine that this class is a gamemode that should show up in the editor and be a playable gamemode.

If we save this as scripts/gamemodes/BasicGamemode.as in our scenario, we will be able to select it in the editor if we have the currently opened .lvl file saved inside of the scenario folder as well.

The above will simply spawn the player in the map without any weapons or HUD. If we wanted to give the player a few weapons for example, we'd add an override for SpawnPlayer provided by BaseGameMode:

void SpawnPlayer(int i, vec2 pos = vec2(), int unitId = 0, uint team = 0) override
{
	BaseGameMode::SpawnPlayer(i, pos, unitId, team);

	// Give weapons
	g_players[i].AddWeapon("weapons/smg.sval");
	g_players[i].AddWeapon("weapons/railgun.sval");

	// Give ammo
	g_players[i].GiveAmmo("weapons/ammo/bolts.sval", 30);
	g_players[i].GiveAmmo("weapons/ammo/bullets.sval", 500);
}

Custom campaign

If you want to base your gamemode on the default Campaign gamemode, setting it up is as smple as inheriting from Campaign:

[GameMode]
class MyOwnCampaign : Campaign
{
	MyOwnCampaign(Scene@ scene)
	{
		super(scene);
	}
}

Your gamemode will then work exactly like the official Campaign gamemode. You can then override methods to modify any of the gamemode behavior.

Versus

We provide a few base gamemodes for versus, in particular VersusGameMode and TeamVersusGameMode. The former is for free-for-all based versus modes (like Deathmatch), and the latter is for team based versus modes (like Team Deathmatch).

A very simple empty versus gamemode kind of resembling Deathmatch would be:

[GameMode]
class BasicVersus : VersusGameMode
{
	BasicVersus(Scene@ scene)
	{
		super(scene);
	}
}

Additions

Default HUD

If you are using BaseGameMode, you probably also want to add a default HUD so you know what's happening. To do this, we have to do a few things:

  • Instantiate a HUD object using the GUI builder
  • Return the object in the gamemode's GetHUD() method
  • Update the HUD in the UpdateWidgets(...) method
  • Render the HUD in the RenderWidgets(...) method

This looks roughly like this:

HUD@ m_hud;

BasicGamemode(Scene@ scene)
{
	super(scene);
	@m_hud = HUD(m_guiBuilder, null);
}

HUD@ GetHUD() override { return m_hud; }

void UpdateWidgets(int ms, GameInput& gameInput, MenuInput& menuInput) override
{
	m_hud.Update(ms);
	BaseGameMode::UpdateWidgets(ms, gameInput, menuInput);
}

void RenderWidgets(PlayerRecord@ player, int idt, SpriteBatch& sb) override
{
	m_hud.Draw(sb, idt);
	BaseGameMode::RenderWidgets(player, idt, sb);
}

Additionally, you can create a class that inherits from HUD and use that instead, if you want to modify any behavior inside of the default HUD. Note: This is not how you add new HUD elements. If you want to add new HUD elements, see Creating an interface.

Properties

Just like with worldscripts, you can have properties in your gamemode that you can modify per level. These are basically variables in your gamemode class with an Editable attribute. Some examples include:

[Editable]
int TimeLimit;

[Editable]
string AuthorName;

[Editable default=10]
int SomeNumber;

GamemodeProperties.png

Functions

Further, you can implement any function you'd like from the below list in your class, and they will be called as events.

void Start(uint8, SValue@, StartMode)
SValue@ Save()

void AddPlayer(uint8)
void RemovePlayer(uint8, bool)

void UpdateFrame(int, GameInput&, MenuInput&)
void UpdatePausedFrame(int, GameInput&, MenuInput&)
void PreRenderFrame(int)
void RenderFrame(int, SpriteBatch&)

void ResizeWindow(int, int, float)
void Paused(bool)

vec2 GetCameraPos(int)
vec4 GetVignette(int)

// Advanced methods
void LobbyCreated(bool loadingSave)
void LobbyInviteAccepted()
void LobbyEntered()

void LobbyDataUpdate()
void LobbyMemberDataUpdate(uint8)
void LobbyList(array<uint64>@)

void SetMenuState(MenuState)
bool MenuBack()
void ShowMessage(MenuMessage)

void OnBindingInput(ControllerType, int)
void ChatMessage(uint8, string)