Left 4 Dead 2

Left 4 Dead 2

Not enough ratings
Simple Guide to Create Vscript Mod with Event Functions
By kurochama
"Have you ever thought that something or some features you want to find aren't available on any mods"
"Have you ever thought about making a vscript mod, but you cancelled that idea because it's complicated enough to make?"

Well, actually making script mods has its own level of difficulty, with editing weapon scripts being the easiest, followed by making mutations by using the available mutation templates. Actually, there's another easier level, & it's making a mod with event functions. Why is it easier? It's because all you need is using the available event function templates to make some features.

Before going further to the examples of some features using event functions, you'll need to prepare to read these references below (or at least just open them on new tabs of browser to check the description of certain functions while making the scripts):

Now, let's go step by step about what you'll need to do first:
  1. Make folders & sub folders of your mod along with the required files, like this:



  2. Open "mapspawn_addon.nut" with "Notepad++" or similar applications, & write something like this:

    This is a script to trigger "your_mod_name.nut" vscript file

  3. The next step is writing scripts & event functions on "your_mod_name.nut". The format of the event function should be "function OnGameEvent_eventname(event)". Writing event functions is quite easy. Here are some examples of simple features along with the scripts:
    • Mod with custom cvars that are triggered on each chapter/ round
      function OnGameEvent_round_start_post_nav(event) { printl("The 'YOUR MOD NAME' mode is started..."); Convars.SetValue("z_tank_health", 99999); Convars.SetValue("grenadelauncher_ff_scale", 0); Convars.SetValue("grenadelauncher_ff_scale_self", 0); Convars.SetValue("survivor_friendly_fire_factor_easy", 0); Convars.SetValue("survivor_friendly_fire_factor_normal", 0); Convars.SetValue("survivor_friendly_fire_factor_hard", 0); Convars.SetValue("survivor_friendly_fire_factor_expert", 0); Convars.SetValue("sb_friend_immobilized_reaction_time_expert", 0.1); Convars.SetValue("sb_friend_immobilized_reaction_time_normal", 0.1); Convars.SetValue("sb_friend_immobilized_reaction_time_hard", 0.1); Convars.SetValue("sb_friend_immobilized_reaction_time_vs", 0.1); }
      - Using this "round_start_post_nav" will allow you to register features, including cvars early on each chapter/ round.
      - "round_start_post_nav" can be used to introduce your mod on console, so it's recommended to always have this one added as one of event functions on the scripts.

    • Infinite Incendiary Ammo (Auto Refill):
      // to check the player's primary weapon function GetPrimarySlot(player) { local invTable = {}; GetInvTable(player, invTable); if(!("slot0" in invTable)) return null; local weapon = invTable.slot0; if(weapon) return weapon.GetClassname(); return null; } function OnGameEvent_weapon_fire_at_40(event) { local player = GetPlayerFromUserID(event.userid); if(player.IsSurvivor()) { // if player's weapon is primary gun if(player.GetActiveWeapon().GetClassname() == GetPrimarySlot(player)) { player.GiveUpgrade(DirectorScript.UPGRADE_INCENDIARY_AMMO); } } }
      This "weapon_fire_at_40" event function is triggered when ammo clip of a gun is only 40% left (examples: 4 ammo clip left for auto shotgun, 15 ammo clip left for desert rifle, etc)

    • Instant Reload on Full Automatic & Semi Automatic Guns:
      function OnGameEvent_weapon_fire(event) { local player = GetPlayerFromUserID(event.userid); if(player.IsSurvivor()) { if(player.GetActiveWeapon().GetClassname() != "weapon_shotgun_chrome" && player.GetActiveWeapon().GetClassname() != "weapon_shotgun_spas" && player.GetActiveWeapon().GetClassname() != "weapon_autoshotgun" && player.GetActiveWeapon().GetClassname() != "weapon_pumpshotgun") { // if the remaining ammo clip is 2 or more if(NetProps.GetPropInt(player.GetActiveWeapon(), "m_iClip1") >= 2) { NetProps.SetPropInt(player.GetActiveWeapon(), "m_bInReload", 1); } } } }
      The netprops "m_iClip1" is used to check ammo clip on a weapon, while "m_bInReload" is to check the reload state.

    • Adrenaline Boost on Pills
      function OnGameEvent_pills_used(event) { local player = null; local pilluser = null; // owner of pills if("userid" in event) { player = GetPlayerFromUserID(event.userid); } // the one who swallowed pills if("subject" in event) { pilluser = GetPlayerFromUserID(event.subject); } if(player == pilluser) { // gets adrenaline speed boost for 10 seconds player.UseAdrenaline(10); } }
      Info for "UseAdrenaline" can be seen on "Script Function" above.

    • Survivor Bot's Auto Aggro on Special Infected's Ability:
      function OnGameEvent_ability_use(event) { local specialinfected = GetPlayerFromUserID(event.userid); if(specialinfected.GetZombieType() <= 8) { local survivorteam = null; while(survivorteam = Entities.FindByClassname(survivorteam, "player")) { if(survivorteam.IsSurvivor() && IsPlayerABot(survivorteam)) { CommandABot({ cmd = DirectorScript.BOT_CMD_ATTACK, bot = survivorteam, target = specialinfected }); } } } } function OnGameEvent_jockey_ride(event) { local jockey = GetPlayerFromUserID(event.userid); local player = GetPlayerFromUserID(event.victim); local survivorteam = null; while(survivorteam = Entities.FindByClassname(survivorteam, "player")) { if(survivorteam.IsSurvivor() && IsPlayerABot(survivorteam)) { CommandABot({ cmd = DirectorScript.BOT_CMD_ATTACK, bot = survivorteam, target = jockey }); } } }
      This feature will make survivor bots automatically detect & target any special infected that's using an ability (tongue, spit, leap, charge, vomit, ride). Well, this is one of useful feature if you want to make survivor bots respond faster via vscript (but it's kind of unfair for special infected team though).

  4. After you finish writing the scripts, drag "Your Mod Name" folder to "vpk.exe" to create a vpk file.

  5. Your vscript mod that uses event functions is ready to use.


There are still many event functions that I don't mention & even I haven't tried all of them yet. With this simple guide, you can try to modify to make your own features. So, just do some fun experiments on your own. You can also try to check some of my mods to study how certain event functions work, as my mods often use event functions to make some features (though probably they might look messy).

& with this, I hope that more people start to be interested in making some simple but fun vscript mods using event functions.
   
Award
Favorite
Favorited
Unfavorite
13 Comments
kurochama  [author] 11 Feb @ 6:12am 
@Absolute Sucker , merging vscript is usually to solve conflicts between two or more mods. The performance might not change as it's simply just like before merging, but with the conflicts solved.
Absolute Sucker 11 Feb @ 5:05am 
@kurochama

Does merging vscript addons improve performance? Is there any other benefit to it?
kurochama  [author] 11 Feb @ 4:55am 
@Absolute Sucker , if both of them are vscript mods, then you can copy-paste the scripts from one vpk file to the other one. Usually this is what I did back then when I wanted to merge some of my mods as one local mod.
Absolute Sucker 11 Feb @ 2:29am 
@kurochama

How can I merge both of these addons? The conflict prevents one of them from taking effect in Hard Rain.

https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2439835745

https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=3228063627
Doc903 9 Dec, 2024 @ 8:47pm 
It's called "nut", because the scripting model is called "Squirrel".
kurochama  [author] 20 Nov, 2024 @ 3:23pm 
xᴜɴᴛᴀ 20 Nov, 2024 @ 1:44pm 
kurochama , Thank u so much. Can you send me the link of your Workshop?
kurochama  [author] 19 Nov, 2024 @ 8:23am 
@˚ʚ ‹3 ɞ˚xᴜɴᴛᴀ , vscript files are usually with "*.nuc" or "*.nut" type. The "*.nuc" type is usually encrypted so it needs to be decrypted via certain tool, while "*.nut" can be edited anytime with Notepad++, without having to decrypt it. That's why "*.nut" type is often used on vscript mods.
xᴜɴᴛᴀ 19 Nov, 2024 @ 8:04am 
kurochama, I'm not referring to the file name, the file type (specifically ".nut")
kurochama  [author] 18 Nov, 2024 @ 9:58pm 
@˚ʚ ‹3 ɞ˚xᴜɴᴛᴀ , if what you meant was "mapspawn_addon.nut", it's because this file will be one of files used to trigger the scripts. There are other 2 files that are often used too, like "director_base_addon.nut" & "scriptedmode_addon.nut". I chose "mapspawn_addon.nut" as it has simpler ways to write event functions there.