Garry's Mod Wiki

Concepts - BaseClasses

Terms and Definitions

A Class is a collection of Functions and Variables defined in code that acts as a template for Instances.
Examples include The Player, Entities, Gamemodes, VGUI Elements, and more.

An Instance is a copy of a Class that is active in the game. There can be multiple Instances of a single Class active at the same time.
For example: When a prop is spawned from the Sandbox Spawn Menu, the game creates an Instance of the Class prop_physics.
The Class prop_physics is only defined in code once but it can be used to create any number of Instances.
To make efficient use of computer hardware, the logic of a Class is not duplicated to each Instance, but instead the Instances all refer back to the same definition in the Class. This is handled via Meta Tables.

A Base Class (or Parent Class) is the set of Functions and Variables that a Class (the Parent Class's Child Class) has by default. The behavior given by (or inherited from) the Parent Class is modified in the Child Class by overriding, replacing, and adding to the Functions and Variables Inherited from the Parent Class. This allows a Class to copy the behavior of another Class without needing to re-create the other Class's logic from scratch. To prevent unnecessary duplication of logic, a Child Class refers to its Parent Class's Meta Table in situations where the Child Class doesn't have an override defined for a Function or Variable.
Note: All Classes must have exactly one (1) Base Class, but can have any number of Child Classes.

How do you use Base Classes?

Example

The following example demonstrates how an Entity can be used as a Base Class for multiple Child Entities.

The Parent Class (sent_parentclass.lua) handles all of the logic for setting up the Entity's model and physics, as well as the logic behind the Entity's unique behavior. In this case, the unique behavior is that some arbitrary visual effect is enabled before the entity draws and is disabled after it draws. In the Parent Class, this visual effect simply turns the Entity blue.

Because the Child Classes (sent_childclass_1.lua and sent_childclass_2.lua) retain the logic of their Base Class (sent_parentclass.lua), they only need to include a very small amount of code to create different visual effects.

sent_childclass_1.lua overrides the function to enable the visual effect and replaces the Parent Class's blue color effect with a rainbow color effect.
sent_childclass_2.lua overrides both the enable and disable functions of the visual effect. They are replaced by functions that make the Entity (Which now looks like a tire) appear to always be rolling, even when stationary.

sent_parentclass.lua

AddCSLuaFile() -- All Entities must have a Base Class. -- In this case, the "base_anim" Class is being used. -- This is one of the default Entity Classes available in Garry's Mod. DEFINE_BASECLASS( "base_anim" ) ENT.PrintName = "Parent Class" ENT.Category = "BaseClass Example" ENT.RenderGroup = RENDERGROUP_TRANSLUCENT ENT.Spawnable = true -- This variable exists to demonstrate that a Base Class provides both -- functions and variables to their children. -- This is a regular-width crate model. ENT.ModelToSpawnWith = "models/props_junk/wood_crate001a_damaged.mdl" -- Set up the Entity function ENT:Initialize() if SERVER then self:SetModel( self.ModelToSpawnWith ) self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) end end -- This is a custom function we'll be using to demonstrate that children can -- override functions from their Base Class. function ENT:EnableVisualEffects() -- Modify upcoming rendering to make it look blue. render.SetColorModulation( 0, 0, 1 ) end -- This custom function won't be overridden by the child Entity, but that is -- purely for demonstration purposes. Any function from the Base Class can -- be overridden by its children. function ENT:DisableVisualEffects() -- Reset the color of the rendering system. render.SetColorModulation( 1, 1, 1 ) end -- Here we use the custom functions above to change how the entity draws. -- Because we do not override this function in the child, this will be the -- Draw function for the child Entity. function ENT:Draw() self:EnableVisualEffects() self:DrawModel() self:DisableVisualEffects() end

sent_childclass_1.lua

AddCSLuaFile() -- Set our Base Class to be the Class we want to inherit functions and values from. -- It would be equally valid to use DEFINE_BASECLASS. -- baseclass.Get() is being used here to demonstrate that both options are viable. ENT.BaseClass = baseclass.Get( "sent_parentclass" ) ENT.PrintName = "Rainbow Child Example" ENT.Category = "BaseClass Examples" ENT.Spawnable = true -- Override the variable in our Base Class that is used to set the Entity's model -- Because we haven't overridden the ENT:Initialize() function, that logic will run -- exactly as it appears in our Base Class, but with this value instead of the value -- defined in the Base Class. -- This is an extra-wide crate model. ENT.ModelToSpawnWith = "models/props_junk/wood_crate002a.mdl" -- Override the visual effects function to randomize the entity's color. function ENT:EnableVisualEffects() local red = math.Remap( math.sin( CurTime() * 2 + 1 ), -1, 1, 0, 1 ) local green = math.Remap( math.cos( CurTime() * 3 + 2 ), -1, 1, 0, 1 ) local blue = math.Remap( math.sin( CurTime() * 4 + 3 ), -1, 1, 0, 1 ) render.SetColorModulation( red, green, blue ) end

sent_childclass_2.lua

AddCSLuaFile() ENT.BaseClass = baseclass.Get( "sent_parentclass" ) ENT.PrintName = "Perpetual Motion Child Example" ENT.Category = "BaseClass Examples" ENT.Spawnable = true ENT.ModelToSpawnWith = "models/props_vehicles/tire001c_car.mdl" -- Replace the Base Class's blue effect with one that makes it look like we're rolling function ENT:EnableVisualEffects() local matrix = Matrix( ) matrix:SetAngles( Angle( 0, 0, CurTime() * 200 ) ) self:EnableMatrix( "RenderMultiply", matrix ) end -- Because we're not changing the Entity's color like the Base Class does, we need to -- override this function to make sure we disable the effect appropriately. function ENT:DisableVisualEffects() self:DisableMatrix( "RenderMultiply" ) end
Output: Below you can see, in order from left to right:
1. The Parent Class sent_parentclass (The blue crate)
2. The first Child Class sent_childclass_1 (The rainbow crate)
3. The second Child Class sent_childclass_2 (The spinning tire)