Garry's Mod

Garry's Mod

27 ratings
Creating a "2D" map for Gmod
By Bump Attack ⊗
This guide will take you through all of the steps required to create a functional, single layer, sidescrolling, 2D map for Garry's mod. This guide is not a tutorial on using hammer, writing lua, or uploading addons to the workshop.
   
Award
Favorite
Favorited
Unfavorite
Folder Creation
First create a folder for your addon. You can name this anything.
Inside, create three folders named: "gamemodes", "lua", and "maps".
These are the folders where you will place everything we create.
Menu Category Creation
Inside of the gamemodes folder, create a text document named "2d".
Inside of the text document write the following and save:
"2d" { "base" "base" "title" "2D" "maps" "^2d-" "menusystem" "0" }
This will create the 2D tab where maps with the prefix "2d_" will appear in game.
Lua Creation
Next, navigate to the lua folder and create a folder named "autorun".
Inside of this folder create a new .lua file using notepad++. This can be named anything.
In this lua file write the following:
if game.GetMap() ~= "2d_map" then return end -- Replace 2d_map with your map's name to run the lua on your map. function MyCalcView(ply, pos, angles, fov, znear, zfar) -- Controls the 2d camera. local view = {} view.origin = pos+(Vector(0, -2000, 75)) -- Sets the Position of the camera relative to the player. view.angles = Vector(0, 90, 0) -- Sets the angle which the camera faces. If you rotate the camera you will need to change it's position. view.fov = 20 -- Sets the field of view. Combine a narrow fov with a far camera in order to create a 2d effect. view.znear = 1800 -- Sets the near z clipping plane. Anything closer to the camera is culled. Allows removing walls between the player and camera. view.zfar = zfar -- Sets the far z clipping plane. Anything too far will be culled. Not useful for 2d. return view end hook.Add("CalcView", "MyCalcView", MyCalcView) hook.Add("ShouldDrawLocalPlayer", "DrawLocalPlayer", function(ply) -- Enables drawing the player's third person model. return true end) hook.Add("InputMouseApply","View",function(cmd,x,y,ang) -- Disables looking left/right and decreases sensitivity of looking up/down. cmd:SetViewAngles(ang+(Angle((y/12), 0, 0))) return true end) hook.Add("CreateMove","Turn1",function(cmd) -- Causes the walk left key to turn the player to the left. if cmd:KeyDown(512) then cmd:SetViewAngles(Angle(0, 180, 0)) -- The new look direction when the key is pressed. This needs to be 90 degrees more than the angle of the camera. cmd:SetSideMove(0) end end) hook.Add("CreateMove","Turn2",function(cmd) -- Causes the walk right key to turn the player to the right. if cmd:KeyDown(1024) then cmd:SetViewAngles(Angle(0, 0, 0)) -- The new look direction when the key is pressed. This needs to be 90 degrees less than the angle of the camera. cmd:SetSideMove(0) end end) if (CLIENT) then local function HideThings( name ) -- Hides the default crosshair which would sit uselessly in the center of the screen. if (name == "CHudCrosshair") then return false end end hook.Add( "HUDShouldDraw", "HideThings", HideThings ) end hook.Add( "PlayerTick", "Collision", function( Player, CMoveData ) -- Disables players colliding with eachother as they cannot walk around one another. Player:SetCollisionGroup( COLLISION_GROUP_PASSABLE_DOOR ) Player:SetAvoidPlayers( false ) end )
Use the notes provided to make adjustments as you see fit. With some tweaking you could probably even create a top down perspective...
Beginning Map Creation
Now to make a map. Begin by opening hammer and starting a new project. When you save make sure to use the prefix "2d_".

The map creation is up to you, just remember to keep everything in a single lane and don't seal off the map in the direction which the camera will view the player from.
It is also important that the "edge" of your 2D map is approximately 3 hammer units closer to the player spawn point than the near z clipping plane. So if you're using the default value the open side of your map should be 197 units from the centre of the player spawn point.
When adding ai nodes to your map make sure they are placed single file and; when possible, use hint nodes configured as such:
Restraining The Player
Sometimes when the player is hit by an enemy, explosion, or prop, they will move slightly to the left or right and become unaligned from the 2D level. To prevent this create two brushes using the player clip tool texture and have them span the entire level. They should be placed around the player spawn point with about 38 hammer units between them.

Advanced Player Restraining

Unfortunately I have observed certain enemies from addons shoving players into the player clips causing them to become stuck. If you're serious, you can remedy this by adding teleporters on each side of the player.

Start by creating three info_targets named "Layer_01_Near_Point", "Layer_01_Reference", and "Layer_01_Far_Point". Place them like this between the player clips:
Next create two trigger_teleport brush entities and place them on each side of the player spawn point with 38 hammer units in between. They should also span the entire map.
Make sure the "clients" flag is set for each and configure them as follows:
Make sure that Layer_01_FarWall is farther from the edge than Layer_01_NearWall.
Restraining NPCs
Although the single file info nodes encourage NPCs to stay aligned with the player there is more we can do to keep them in line. This next step is only important if you try to add other layers to your 2D map as it prevents NPC's from seeing between layers.

To block NPC line of sight, simply use the block los tool texture to create two more brushes that span the entire map. These don't need to be very close together and I've placed them 140 units apart.

At this point there is still nothing physically restraining npc's to the 2D layer. This is a problem because many of the default enemies from HL2 will wander away from nodes when idle. Zombies and combine specifically will frequently walk out of the 2D lane where you cannot shoot them.

Advanced NPC Restraining

In order to fix this we can create two more brushes with the NPC clip tool texture which will span the map. However some enemies are wider than others and will become stuck if we do this. To fix this we must make the clip's collisions specific to one entity class by turning them into func_brush entities and spacing them far enough apart for this NPC type.

Here I have placed the clips 38 units apart and converted them into func_brushes which only collide with combine soldiers:
You will need to do this for each default hostile NPC if you don't want any of them to be able to wander or walk around obstacles in 3D. Yes, I know it's tedious, but the only other option is to try using lua and that probably wouldn't end well.
Locking Vehicles
Unlike the player, vehicles can move in 3D space on this map. In order to prevent this we can use a single map wide trigger. Create a trigger_multiple brush entity which covers all of the map, set the "everything (not including physics debris)" flag and give it the following output:
This will automatically lock any vehicle on the map. However, if your map has doors or buttons it will lock them as well. To prevent this assign your trigger_multiple a filter.
Create a filter on the map with this name and configure it like this:
This will prevent the trigger_multiple from locking any entity which has a name. Now all you need to do is give any doors or buttons a unique name.
Sealing The Fourth Wall
Now it's time to seal off the map. Instead of simply covering the open wall, you need to create a large open space for the camera. Even though the near z clipping plane culls out things too close to the camera, the camera must be in bounds. If it is out of bounds the game will not render the skybox or some other things as if the player were out of bounds.

If you're using the default values the camera will be 2000 units away, and 75 units up from the player. Make sure that there is open space this far away.
If your map has water that is raised above ground level you will need to make sure that it does not reach the near z clipping plane and is properly sealed. If your map has water that is below ground level make sure that you extend it outwards the full 2000 units so that the camera will go underwater.
Now re-texture any exposed faces to the black tool texture.
Then add your skybox. Here I have put the black that will appear in the ground and around the structure in the skybox.
Finally you can add a solid wall across the open side of your map as it will be culled out by the near z clipping plane. Here I have used a brush textured with the block light tool texture instead as there is no way to see the outside wall on this map.
Finishing The Addon
Now that the map is complete it's time to compile!
Place the finished .bsp in the maps folder from earlier.
Then place the entire addon folder into your gmod addons folder.
Your map should now appear in game!
From this point you can convert your addon into a .gma and then upload it to the workshop so that all may revel in it's flatness!
9 Comments
dsaS Nov 10, 2023 @ 8:05pm 
Goblin Girl Dater Dec 7, 2020 @ 1:50pm 
how do i make building easier?
Rowie 9811 Nov 29, 2020 @ 2:46pm 
ti's Super Mario maker 3
Bump Attack ⊗  [author] Nov 26, 2020 @ 2:25pm 
Bump Attack ⊗  [author] Nov 24, 2020 @ 6:27am 
I isn't on the workshop yet. I'm going to upload it alongside a 2d NES Super Mario Brothers map in the near future.
Slash Nov 23, 2020 @ 9:48pm 
where's the NES mario playermodel that you used?
Takashi Strauss Nov 20, 2020 @ 3:00pm 
I like how you used Super Mario
Gronile Longfinger Nov 19, 2020 @ 1:22am 
Cool!
CHALAPS Nov 15, 2020 @ 4:08am 
thank you