[Addons Application] Rito Munro Fraser

May 14, 2023
67
9
41
20
Denmark
In-game name: Rito Munro Fraser
Steam ID: STEAM_0:1:45160495
Age: 20
For how long have you played on our servers?: ~2 Years - I have 1069 hours on SCP:RP according to the 1 Year achievement
What country are you from?: Denmark
Time Zone: CET (GMT+1)
Do you have a mic?: Yes

Is this your first application for Developer? If not, link previous ones: This is my first Dev application

Have you received any bans?: No

How confident are you with GLua? (Rate yourself 1-10 using rating guide): I'd put myself at a 5

Do you have any experience with Git?: Although not extensive, I have on multiple occasions used Git for collaborative work and version control for personal projects.

Do you have previous experience as a Developer for GMod?: Outside of making addons purely for practicing GLua, no.

How many hours can you commit to developing per week?: I am unsure, but would estimate 10-15 hours, although may be higher at times, depending on if I'm busy or not.

Why do you want to be a Developer? What can you help us with?: Given the large quantity of time I have spent on the server, I, like many others, really enjoy and appreciate the community that is CivilNetworks (SCP:RP specifically in my case). As such I would love to be given the chance to help the community improve.

I frequently hear (and occasionally partake myself too) players talk about how they wish the server received more updates, and the general response is typically that there isn't enough developer resources to address the player's demands. Given that I have a large amount of experience (and interest) in programming, I thought it would be a good opportunity for me to help.

My reasoning for rating myself 5/10, in terms of GLua confidence, is that my experience with developing on gmod is not too extensive. However, what I do have extensive knowledge in is Luau, a fork of Lua developed and maintained by Roblox Corporation. Luau, being a fork of Lua, is fully compatible with Lua code, and as such I am extremely familiar with Lua syntax, and as an extension of that, have found GLua syntax to be similar too.

As mentioned, I have a lot of experience with Luau. This experience is from doing game development on the Roblox platform over the span of 8 years.
In those 8 years, I have worked on, and released, multiple games onto Roblox, totalling more than 20 million impressions (individual plays, not unique players). While Roblox' API and design patterns differ from those of gmod GLua, I believe many of my skills from this past experience carries over.

Additionally, I am currently 3 semesters deep into getting my bachelors degree in Computer Science, which I hope speaks to my investment in the topic of programming, and to some degree my knowledge of the field.

I would love to show some of my previous code, unfortunately I will not show the code from the aforementioned Roblox games, as some of them are still operating. However, like I mentioned, my GLua experience consists of me writing addons to practice my GLua skills, and to get used to the gmod APIs, as such, I have in the past 2 days developed 2 addons that I would like to share:




GitHub Link: SCP-682 SWEP
Video: Link
Description:
This addons adds a single SWEP to the game, titled "SCP 682". Upon equipping this SWEP, all other weapons are cleared from the players inventory, their model is changed to that of SCP 682, and a UI will appear at the top of their screen.

Just as on SCP:RP, the SCP 682 SWEP has a left click bite attack, and a right click roar attack.
The bite does damage in an AoE in front of the player, and the roar stuns nearby players.
Unlike on the SCP:RP server, this SWEP tracks a stat for 682 called "Regenerative Force", which is reduced upon taking damage, but increases with each kill, capping at 300%.
This stat scales the size, regen, and max health of SCP-682, which I feel is more inline with the lore of the SCP.

Do note: The stun of the roar currently only applies to players, and not NPCs. This is due to how HL NPCs use weapons, and is hard for me to fix without significant effort (at least as far as I could figure out)




GitHub Link: Money System
Image:
R1pGM4R.png

Description:
This one is pretty much taken directly from the grading guide. 😄
It is a primitive money system, which includes a UI at the top of the screen, that shows how much money the player is currently carrying.
The addon adds an "ATM" entity, which uses imgui, a 3D2D library, for its UI. This ATM allows the player to withdraw or deposit money to their bank account.
Both the player's wallet and bank account is saved to a file using JSON encoding, and is properly loaded upon joining the game.
Please do note that I haven't gotten around to cleaning up the code for this addon yet, so it might be a bit messy, I usually like to ensure the functionality is right before I start refactoring to make the code cleaner.




While these codebases may not be perfect, or may go against some standard practices I am unaware of, please take into account that this is what I was able to produce in the span of 2 days on the side of working on assignments and playing on the server, while being mostly unfamiliar with GLua.

If you remain unconvinced of my capabilities, please feel free to reach out to me, and I will do me best to address any concerns.

Thank you for reading.
 
Last edited:
+Support

  • + Active.

  • + Have only stood behind this individual while being a cardboard cutout of CI had good interactions with this individual.

  • + Has been around on SCP-RP for a while and therefore would reasonably have a good understanding of the community and what would be good to develop for the server, etc.

  • -/+ So,
Upon equipping this SWEP, all other weapons are cleared from the players inventory, their model is changed to that of SCP 682
While I get the intent of this functionality, it doesn't really make sense within the context of the server - The 682 job itself is configured somewhat in isolation from other jobs, with a set model and to have only the SWEPs and such that it needs, so while for demonstration purposes, setting the model and clearing the other equipped items is pretty cool, but when thinking about practically using this on the server, is actually a little bit less then useless? As this would be... Not unusable for events? Since you could equip this SWEP first, then just change your model and get all the other SWEPs you need where necessary, via commands, but you can see how it could be obstructive/annoying to deal with any time you wanted to use it for whatever reason.

I know there's only some very specific use cases to use a 682 SWEP for an event, but I'm trying to get this across in the sense that, imagine if a lot of SWEPs were made in this way, like say you make a defib SWEP and it sets your model to the combat medic model then does a bunch of other things that are, not really unrelated to the use of the SWEP, just kind of adjacent to its use and not really needed, when thinking about having the SWEP in situ.

But imo that's kind of a small nitpick, looking at everything else, you should be fine so long as you occasionally take a step back and think about other ways in which a SWEP could be used, that your current implementation could be impacting in some way by something that is not strictly necessary for the SWEP.

I think there's potential here.
 
Last edited:

Lion

Senior Developer
Senior Developer
Programming Team
Aug 26, 2023
69
15
21
United States
www.github.com
+support

Addons look pretty nice from a user standpoint, but the code quality is definitely something that needs to be improved if brought onto the team.
Here's a general list of improvements that could be made to your existing work:

682 Swep​

  • Font creation / usage
    • You don't need to include all the font data in the table, it's generally considered bad practice because it clutters up the code (link)
    • The fonts created here should have a name that prevents it from possibly conflicting with other addons -- something like "SCP682:TitleFont" (link)
  • Configuration
    • These should either be put as variables in the SWEP's table, or put under a global table. (link)
  • General Code Style -- Just generally how things are written, not specific to parts of the addon
    • Many comments are self-explanatory and shouldn't exist
    • You should put space around operators, including after commas in function names
      • This is mainly just personal preference, but it's what most of the gmod community has agreed on

ATM Addon​

  • Vague naming of the autorun files make its it prone to being accidently overwritten by other addons
    • There should usually only be one autorun file, named something similar to (sh_my_addon_init.lua)
  • The same font creation thing, you don't need to define all these (font, weight, and size is usually enough) (link)
  • I'm not entirely sure why you're wrapping this network message in a coroutine, I don't think I've ever seen anyone do this. (link)
  • It would be useful to have some comments in here about what is being drawn and where (link)
  • Your network message name should also be namespaced to your addon. Something like (MyAddon:BankAction) (link)
  • The logic on the client and server is really confusing to look at when dealing with withdrawing / depositing money. (link)
    • Here's a quick refactor I did using enums, along with assuming some deeper SQL support (which is required for any civil networks addon that saves player data):
    • Code:
      -- SHARED
      MyBank = MyBank or {}
      
      -- These allow us to still send uints through the network channel,
      -- and still have readable code
      MyBank.Actions = {
          Withdraw = 1,
          Deposit = 2
      }
      
      -- SERVER
      util.AddNetworkString("MyBank:BankAction")
      
      net.Receive("MyBank:BankAction", function(_, ply)
          local action = net.ReadUInt(2) -- we only need 2 bits (allows 3 as the max value)
          local amount = net.ReadUInt(32)
      
          if (amount == 0) then return end
      
          -- Using enums like this allows future programmers to
          -- read the code much easier
          if (action == MyBank.Actions.Withdraw) then
              if (not MyBank.CanAfford(ply, amount)) then return end
      
              MyBank.SQL.Withdraw(ply:SteamID64(), amount, function(ok)
                  if (not ok) then return end
      
                  ply:addMoney(amount) -- darkrp's addMoney function
                  MyBank.NetworkBalance(ply)
                  DarkRP.notify(ply, NOTIFY_GENERIC, 5, string.format("You've withdrawn %s from your bank account!", DarkRP.formatMoney(amount)))
              end)
          elseif (action == MyBank.Actions.Deposit) then
              if (not ply:canAfford(amount)) then return end -- darkrp's canAfford function
      
              ply:addMoney(amount * -1)
              MyBank.SQL.Deposit(ply:SteamID64(), amount, function(ok)
                  if (not ok) then return end -- this should probobly also give the money
                                              -- taken from the user's wallet back as well
      
                  MyBank.NetworkBalance(ply)
                  DarkRP.notify(ply, NOTIFY_GENERIC, 5, string.format("You've deposited %s into your bank account!", DarkRP.formatMoney(amount)))
              end)
          else
              -- do some real error handling here
          end
      end)
      
      -- CLIENT
      
      -- note: idealy, these pixel values would not be hardcoded, and would be
      -- setup for scaling to any size screen
      if imgui.IsPressed() then
          local action
          if imgui.IsHovering(52, 160, 144, 50) then -- withdraw button
              action = MyBank.Actions.Withdraw
          elseif imgui.IsHovering(204, 160, 144, 50) then -- deposit button
              action = MyBank.Actions.Deposit
          elseif imgui.IsHovering(52, 100, 30, 50) then -- increment amount button
              self.Increment = math.max(self.Increment - 1,1) -- todo: give this var a better name
          elseif imgui.IsHovering(318, 100, 30, 50) then -- decrement amount button
              self.Increment = self.Increment + 1
          end
      
          if action then -- null is falsey
              net.Start("MyBank:BankAction")
                  net.WriteUInt(action, 2)
                  net.WriteUInt(self.Increment, 32)
              net.SendToServer()
          end
      end
  • The libs folder should be inside another folder in the root of the lua directory. Something like (lua/my_addon/libs/cl_imgui.lua)

Overall, you seem very promising and we always need more developers. With your stated time commitment, I have no doubts that you would be able to pick up our standards quick enough to be a productive member of the team.

Thanks for making this application.
 
May 14, 2023
67
9
41
20
Denmark
+support

Addons look pretty nice from a user standpoint, but the code quality is definitely something that needs to be improved if brought onto the team.
Here's a general list of improvements that could be made to your existing work:

682 Swep​

  • Font creation / usage
    • You don't need to include all the font data in the table, it's generally considered bad practice because it clutters up the code (link)
    • The fonts created here should have a name that prevents it from possibly conflicting with other addons -- something like "SCP682:TitleFont" (link)
  • Configuration
    • These should either be put as variables in the SWEP's table, or put under a global table. (link)
  • General Code Style -- Just generally how things are written, not specific to parts of the addon
    • Many comments are self-explanatory and shouldn't exist
    • You should put space around operators, including after commas in function names
      • This is mainly just personal preference, but it's what most of the gmod community has agreed on

ATM Addon​

  • Vague naming of the autorun files make its it prone to being accidently overwritten by other addons
    • There should usually only be one autorun file, named something similar to (sh_my_addon_init.lua)
  • The same font creation thing, you don't need to define all these (font, weight, and size is usually enough) (link)
  • I'm not entirely sure why you're wrapping this network message in a coroutine, I don't think I've ever seen anyone do this. (link)
  • It would be useful to have some comments in here about what is being drawn and where (link)
  • Your network message name should also be namespaced to your addon. Something like (MyAddon:BankAction) (link)
  • The logic on the client and server is really confusing to look at when dealing with withdrawing / depositing money. (link)
    • Here's a quick refactor I did using enums, along with assuming some deeper SQL support (which is required for any civil networks addon that saves player data):
    • Code:
      -- SHARED
      MyBank = MyBank or {}
      
      -- These allow us to still send uints through the network channel,
      -- and still have readable code
      MyBank.Actions = {
          Withdraw = 1,
          Deposit = 2
      }
      
      -- SERVER
      util.AddNetworkString("MyBank:BankAction")
      
      net.Receive("MyBank:BankAction", function(_, ply)
          local action = net.ReadUInt(2) -- we only need 2 bits (allows 3 as the max value)
          local amount = net.ReadUInt(32)
      
          if (amount == 0) then return end
      
          -- Using enums like this allows future programmers to
          -- read the code much easier
          if (action == MyBank.Actions.Withdraw) then
              if (not MyBank.CanAfford(ply, amount)) then return end
      
              MyBank.SQL.Withdraw(ply:SteamID64(), amount, function(ok)
                  if (not ok) then return end
      
                  ply:addMoney(amount) -- darkrp's addMoney function
                  MyBank.NetworkBalance(ply)
                  DarkRP.notify(ply, NOTIFY_GENERIC, 5, string.format("You've withdrawn %s from your bank account!", DarkRP.formatMoney(amount)))
              end)
          elseif (action == MyBank.Actions.Deposit) then
              if (not ply:canAfford(amount)) then return end -- darkrp's canAfford function
      
              ply:addMoney(amount * -1)
              MyBank.SQL.Deposit(ply:SteamID64(), amount, function(ok)
                  if (not ok) then return end -- this should probobly also give the money
                                              -- taken from the user's wallet back as well
      
                  MyBank.NetworkBalance(ply)
                  DarkRP.notify(ply, NOTIFY_GENERIC, 5, string.format("You've deposited %s into your bank account!", DarkRP.formatMoney(amount)))
              end)
          else
              -- do some real error handling here
          end
      end)
      
      -- CLIENT
      
      -- note: idealy, these pixel values would not be hardcoded, and would be
      -- setup for scaling to any size screen
      if imgui.IsPressed() then
          local action
          if imgui.IsHovering(52, 160, 144, 50) then -- withdraw button
              action = MyBank.Actions.Withdraw
          elseif imgui.IsHovering(204, 160, 144, 50) then -- deposit button
              action = MyBank.Actions.Deposit
          elseif imgui.IsHovering(52, 100, 30, 50) then -- increment amount button
              self.Increment = math.max(self.Increment - 1,1) -- todo: give this var a better name
          elseif imgui.IsHovering(318, 100, 30, 50) then -- decrement amount button
              self.Increment = self.Increment + 1
          end
      
          if action then -- null is falsey
              net.Start("MyBank:BankAction")
                  net.WriteUInt(action, 2)
                  net.WriteUInt(self.Increment, 32)
              net.SendToServer()
          end
      end
  • The libs folder should be inside another folder in the root of the lua directory. Something like (lua/my_addon/libs/cl_imgui.lua)

Overall, you seem very promising and we always need more developers. With your stated time commitment, I have no doubts that you would be able to pick up our standards quick enough to be a productive member of the team.

Thanks for making this application.
Hello,
I really appreciate the feedback, I feel I have gotten a better grasp GLua conventions with the list of improvements you provided.
I've gone ahead and addressed a lot of the points you brought up.
I haven't redone the Ui for the ATM addon, despite me wanting to, since it would be a good amount of work, for an addon that I will realistically never use.
I have however gone ahead and switched it over to using a SQL rather than JSON, I hope this can speak in regards to my learning-rate and adaptability.
Once again, thank you for the feedback, it was very informative.
 
Aug 27, 2022
223
29
91

Hey @Rito Munro Fraser,​

I checked out your code last night and noticed some things that Lion listed, especially the SWEP UI FontData.​

I also noticed that some functions within the SWEP CL and shared were not in the "correct" place and can cause bugs/errors (sound, etc.) when in multiplayer.​

I think you would be a great developer +SUPPORT .

Edit: I noticed you made changes and edited most of the listed issues. It's great to see you actively updating it, +support.
Good luck,
Jamarion