Skip to content
RustPluginGenerator

OnMissionStart

OnMissionStart is called by BaseMission.MissionStart before the mission's objectives are initialised for a player. Returning a non-null value cancels the start so the objective loop never runs.

Signature
object OnMissionStart(BaseMission mission, BaseMission.MissionInstance missionInstance, BasePlayer assignee)

Parameters

Hook parameters
ParameterTypeDescription
missionBaseMissionThe BaseMission entity that is being started, e.g. the mission game object holding the objectives array. Use mission.ShortPrefabName or net.ID to identify which mission type is running.
missionInstanceBaseMission.MissionInstanceThe per-assignee MissionInstance holding the objective progression, timer and completion state. Null-check it before touching its fields; it is the object the game mutates while objectives advance.
assigneeBasePlayerThe BasePlayer the mission is started for. May be null when the game starts a mission without a direct assignee, so guard before reading UserIDString or transform.

Return value

Return null (or nothing) to let the mission start normally and initialise its objectives. Return any non-null object to abort MissionStart before the objective loop, so the instance is not set up for the assignee.

How it works

The hook fires once per BaseMission.MissionStart(instance, assignee) call, right at the top of the method and before the objectives array is looped over. The game calls MissionStart when a player is assigned a spawned mission and objectives need to be activated for that instance. mission is the mission entity (its type and prefab tell you which mission it is), missionInstance is the mutable state that tracks objective progress for that player, and assignee is the player receiving it.

Because the call sits in front of the objective loop, it is the last safe point to refuse a mission: nothing has been assigned yet, so cancelling leaves the player without objectives and without a half-initialised instance. You cannot narrow dispatch by declaring a more specific parameter type here unless the game passes that exact subclass for every call, which it does not; check the mission type inside the hook instead.

Use it for gating mission access (permissions, groups, playtime, team state) and for announcing starts to other players. It fires per start, not per objective, so keep it cheap and avoid per-tick work.

Example plugin: Restrict missions to permission holders with a chat notice

MissionPermissionGate.cs
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Mission Permission Gate", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts mission starts to players with a permission and announces valid starts.")]
    public class MissionPermissionGate : RustPlugin
    {
        private const string PermUse = "missionpermissiongate.use";

        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Blocked"] = "You do not have access to missions yet.",
                ["Announce"] = "{0} has started a mission: {1}"
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, userId), args);
        }

        private object OnMissionStart(BaseMission mission, BaseMission.MissionInstance missionInstance, BasePlayer assignee)
        {
            if (mission == null || missionInstance == null || assignee == null)
                return null;

            if (assignee.IsAdmin || permission.UserHasPermission(assignee.UserIDString, PermUse))
            {
                string missionName = mission.GetType().Name ?? "unknown";
                Server.Broadcast(Msg("Announce", null, assignee.displayName, missionName));
                return null;
            }

            assignee.ChatMessage(Msg("Blocked", assignee.UserIDString));
            return false;
        }
    }
}

The plugin registers a missionpermissiongate.use permission and, in OnMissionStart, checks the assignee against it (or IsAdmin). When the player lacks access, the hook returns false, which stops the mission start. Players who are allowed get a server-wide broadcast naming the player and the mission's runtime type name, using the Announce language string. Null checks on mission, missionInstance and assignee keep NPC or unsolicited starts from throwing. No config is needed, so the plugin stays a single focused file; messages live in the language file so admins can translate them.

Common use cases

  • Rank-gated mission access

    Check a permission or a group before allowing the mission; return a non-null object to block it for players who have not earned access, and notify them through lang messages.

  • Team state checks

    Read assignee.currentTeam and refuse the start when the player is not in a team or their team leader has missions disabled, so group servers can keep mission progress per squad.

  • Mission announcements

    Post a server-wide message when a mission starts for a player, using mission identity to name the objective set, without modifying the game path.

Pitfalls

  • Assignee can be null

    The game may start a mission without a direct player reference. Dereferencing assignee.UserIDString or reading transform without a null check throws inside the hook and can break the start path for every mission.

  • Cancelling leaves no objectives

    A non-null return skips the objective loop entirely, so the player receives a mission instance that will never progress. Only cancel when you intend to (and have a way to) prevent the assignment from happening elsewhere.

  • Runs per start, not per player

    Do not assume one call per player session; the mission system may start instances for other assignees. Keep the hook cheap and never use PrintWarning or heavy loops inside it.

Build a plugin with OnMissionStart

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Rank-gated mission access using the OnMissionStart hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnMissionStart

Generate