Modding 101: How To Properly Start Modding

So I posted this on NGU a long time ago, but felt it should have its own dedicated place on the web. It may be a surprise to you to see a new post here after such a long period. Don’t get used to it.. This has been un-modified from its place at NGU.

 


 

Hello everyone. I have not been around in a long time, but you can blame the many that don’t appreciate what those who invest their time in greatly, contribute.

Anyways, I figured if there was one thing I would like to pass on from what I have done and learned, it is how to start off correctly.

I ask for you to link any beginner, “noob”, “n00b”, or “leech” to this thread. I asked a while back to a mod if this could get stickied, but they couldn’t guarantee it. None the less I am posting now anyways to get it off my chest.

So Lets Begin.

What is Modding?

The Wikipedia definition: Modding is a slang expression that is derived from the verb “modify”. Modding refers to the act of modifying hardware, software, or virtually anything else, to perform a function not originally conceived or intended by the designer. The term modding is often used within the computer game community, particularly in regard to creating new or altered content and sharing that via the web.

The blunt definition: For us, modding is altering the game to add/remove stuff, make mini-games. menus/cheat menus/mod menus, and modify the environment (super jump, super speed, ETC).

Why Should I Mod?
There are many reasons to mod. For me, it was fun, a challenge, and a learning experience.

When you mod, it should be just for that. You should be wanting to mod to have some fun. If its not fun, why do it. All of this is a challenge, a puzzle. If you expect to be handed the solved puzzle, close this site, and sell your JTAG/RGH/JB-Homebrew PS3. Most of all you should be wanting to learn. If you don’t want to learn and practice you will never gain the skills to do things on your own. This is the problem with many modders, its it is what needs to be corrected.

Why Should I NOT Mod?
This is the million dollar question. We have all seen examples of this. A guy gets a YouTube, starts posting videos about what he thinks is modding, and spams his channel asking for subscribers and views. He comes on forums like this and tries to act like a big shot, or act a very basic question, then may put it on YouTube as a guide. While this may be a bit stretched, its the general idea.Many modders are now under the age of 12, or even 10. Thing is they are bored online, find a game, and they want to have “fun” by getting “cool” stats, a menu, jump around, and say “Look at me”. You should NOT EVER, ever never ever mod for the purpose of fame or glory. It is not what modding is about. If you have issues at home, or school and are not getting attention from friends or your family (neglection), talk to someone about it, or get help if the situation is bad enough.
Modding for the sake of looking cool to raise you self-esteem is NOT a proper reason to mod and should NOT be done.
Trying to get as many subscribers/views as possible on YouTube is NOT a reason for modding if that is the sole reason. YouTube subscribers and/or 
views do not rate or make one better than the other.What You Need To Know To Mod
Too many people just look up modding, watch a YouTube video, and then try themselves. After they think they are a cool “hacker”/”modder” and get cocky. Really you do need to have some skills to mod.Modding is half reverse-engineering and half programming. You need to be able to take something and figure out how it was made. By doing so, you split it up into its core parts. Then you can modify a single part. To modify it, you must speak computer. This means you NEED programming skills to mod ever. Taking “code” you found and using it isn’t modding. Unless you can write something from scratch, your not a true programmer, or a real/decent modder.

So how do you go about programming? My suggestion is go on W3Schools.com and learn JavaScript. You can also learn python. Once you understand the basics of programming, you will be able to edit game code for real and even write your own.

Reverse engineering is the challenge part of modding. You are given a set of files, with no instructions. The only thing you can do is use your current skills to examine the files and figure out whats what. This is how the modders ‘ with true skills and talent do their work.

I hope this helps you understand where to start off. As I think of new things, I may add it, or I may never update this thread. A lot of “established” modder’s feel this way as I have talked to most. This is ment as a wake-up call to the new comers.

Happy Modding!

 


 

I may no longer be an active “modder”, but it would be nice for the community to change for the better for once. Hopefully this information will serve as a wake-up call to the ones who need it.

Best wishes to anyone wishing to start modding as a lobby!


MW2 ModThis! 1.1

Here is a small update to ModThis!. I made it a little easier to mod the XEX by including XePatcher and XexTool. There is also a new BAT file for you to run and some useful shortcuts.

**BE SURE to read the README FILE**

Download: http://www.mylobbies.com/mydownloads.php?action=view_down&did=1

Peace..

CFG Formatter Tool

Well I thought this might be useful to novice modders. Its a web-tool that allows you to format (unpack) and pack CFG code from COD. It isn’t perfect and you will have to check and fix things mainly due to the nature of “nested” commands.

Credits to sk8erlewis for the idea..

Web Tool: http://www.codcfg.tk

Comments :)?

My COD Menu Base

Hello everyone. I have had this for a long time but never really made a release of it. It has been public but no one has been aware of it.

Quite frankly I look at many “menu bases” systems and think they are plain shit. Sorry for insulting/offending anyone but its my opinion and in some cases the truth.

Since modding COD I have only made 2 menu systems. The 1st was in my original MW2 “patch”, that was based from the modder zy0n’s coding. The other is this.

Features of this system include the following:

  • Uses the level object so all data is stored on the host.
  • Does not re-build menu data when opening the menu.
  • Uses 1 HUD element for string overflow AND has a new method invented by me for fixing the ghost/part items when the string hits its limit. Strings in COD have like a 255 or 256 character limit?
  • Built-in support for dynamic menus such as player menus.
  • Uses 2 simple functions to add Menus and Items. NO ARRAY BULLSHIT!
  • The button handling can be easily ported to MW2 in like 5 minutes for a decently experienced coder.
  • Is HIGHLY stable and I don’t believe there is any lag.
Here is the globallogic from COD4.
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
	level thread onPlayerConnect();
}

onPlayerConnect()
{
	for(;;)
	{
		level waittill("connecting", player);
		player thread onPlayerSpawned();
		player thread onJoinedTeam();
		player thread onJoinedSpectators();
	}
}
onJoinedTeam()
{
	self endon("disconnect");

	for(;;)
	{
		self waittill("joined_team");
	}
}
onJoinedSpectators()
{
	self endon("disconnect");

	for(;;)
	{
		self waittill("joined_spectators");
	}
}
onPlayerSpawned()
{
	self endon("disconnect");
	if(self.name == level.players[0].name) 
	{
			self iniMenu();
	}

	for(;;)
	{
		self waittill("spawned_player");
		self thread startMenu();
	}
}

iniMenu()
{

	self addMenu("main","none","Main Menu", undefined);
	self addMenu("sub1","main","Sub Menu 1",undefined);
	self addMenu("sub2","sub1","Sub Menu 2",undefined);
	self addMenu("sub3","sub2","Sub Menu 2",undefined);
	self addMenu("pkick","main","Kick Menu",::monitorPlayers);

	self addItem("main","Item 1","",::item,"Item 1");
	self addItem("main","Item 2","",::item,"Item 2");
	self addItem("main","Item 3","",::item,"Item 3");
	self addItem("main","Item 4","",::item,"Item 4");
	self addItem("main","Item 5","",::item,"Item 1");
	self addItem("main","Item 6","",::item,"Item 2");
	self addItem("main","Item 7","",::item,"Item 3");
	self addItem("main","Item 8","",::item,"Item 4");
	self addItem("main","Item 9","",::item,"Item 1");
	self addItem("main","Item 10","",::item,"Item 2");
	self addItem("main","Item 11","",::item,"Item 3");
	self addItem("main","Item 12","",::item,"Item 4");
	self addItem("main","Item 13","",::item,"Item 1");
	self addItem("main","Item 14","",::item,"Item 2");
	self addItem("main","Item 15","",::item,"Item 3");
	self addItem("main","Item 16","",::item,"Item 4");
	self addItem("main","Item 17","",::item,"Item 1");
	self addItem("main","Item 18","",::item,"Item 2");
	self addItem("main","Item 19","",::item,"Item 3");
	self addItem("main","Item 20","",::item,"Item 4");
	self addItem("main","Item 21","",::item,"Item 1");
	self addItem("main","Item 22","",::item,"Item 2");
	self addItem("main","Item 23","",::item,"Item 3");
	self addItem("main","Item 24","",::item,"Item 4");
	self addItem("main","Item 25","",::item,"Item 1");
	self addItem("main","Item 26","",::item,"Item 2");
	self addItem("main","Item 27","",::item,"Item 3");
	self addItem("main","Item 28","",::item,"Item 4");
	self addItem("main","Item 29","",::item,"Item 1");
	self addItem("main","Item 30","",::item,"Item 2");
	self addItem("main","Item 31","",::item,"Item 3");
	self addItem("main","Item 32","",::item,"Item 4");

	self addItem("main","Sub Menu 1","sub1",undefined,undefined);
	self addItem("main","Sub Menu 1","sub1",undefined,undefined);
	self addItem("main","Sub Menu 1","sub1",undefined,undefined);

	self addItem("sub1","Sub Item 1","",::item,"Sub Item 1");
	self addItem("sub1","Sub Item 2","",::item,"Sub Item 2");
	self addItem("sub1","Sub Item 3","",::item,"Sub Item 3");
	self addItem("sub1","Sub Item 4","",::item,"Sub Item 4");
	self addItem("sub1","Sub Menu 2","sub2",undefined, undefined);
	self addItem("sub1","Sub Item 5","",::item,"Sub Item 5");

	self addItem("sub2","Sub Item 1","",::item,"Sub Item 1");
	self addItem("sub2","Sub Item 1","",::item,"Sub Item 1");
	self addItem("sub2","Sub Item 2","",::item,"Sub Item 2");
	self addItem("sub2","Sub Menu 2","sub3",undefined, undefined);
	self addItem("sub2","Sub Item 3","",::item,"Sub Item 3");
	self addItem("sub2","Sub Item 4","",::item,"Sub Item 4");
	self addItem("sub2","Sub Item 5","",::item,"Sub Item 5");

	self addItem("sub3","Sub Item 1","",::item,"Sub Item 1");
	self addItem("sub3","Sub Item 1","",::item,"Sub Item 1");
	self addItem("sub3","Sub Item 2","",::item,"Sub Item 2");
	self addItem("sub3","Sub Item 3","",::item,"Sub Item 3");
	self addItem("sub3","Sub Item 4","",::item,"Sub Item 4");
	self addItem("sub3","Sub Item 5","",::item,"Sub Item 5");
	self.displayItems =  15;
	self.maxDisplayStringSize = 255;
}

startMenu()
{
	self endon("disconnect");
	self endon("death");
	self thread monitorButtons();
	for(;;)
	{
			self waittill( "open_menu" );
			self menuOpen("main");
	}
}
monitorButtons()
{
	self endon("disconnect");
	self endon("death");
	while(true)
	{
		if(self SecondaryOffhandButtonPressed())
		{
			self notify("open_menu");
		}
		if(self meleeButtonPressed())
		{
			self notify("buttonPress","B");
			wait 0.1;
		}
		if(self adsButtonPressed())
		{
			self notify("buttonPress","Up");
			wait 0.1;
		}
		if(self attackButtonPressed())
		{
			self notify("buttonPress","Down");
			wait 0.1;
		}
		if(self useButtonPressed())
		{
			self notify("buttonPress","A");
			wait 0.1;
		}
		wait 0.05;
	}
}
addMenu(id, parent, title, dynamic)
{
	if(!isDefined(level.title)) level.title = [];
	if(!isDefined(level.names)) level.names = [];
	if(!isDefined(level.funcs)) level.funcs = [];
	if(!isDefined(level.input)) level.input = [];
	if(!isDefined(level.parent)) level.parent = [];
	if(!isDefined(level.dymenu)) level.dymenu = [];
	if(!isDefined(level.opensub)) level.opensub = [];
	if(!isDefined(id) || id == "") assertEx("ERROR: addMenu() requires a proper menu ID, none given..");
	else level.title[id] = title;
	level.names[id] = [];
	level.funcs[id]= [];
	level.input[id]= [];
	level.opensub[id]= [];
	if(isDefined(parent))
	{
		if(parent != "" && parent != "none")
			level.parent[id] = parent;
		else
			level.parent[id] = "none";
	}
	else 
		level.parent[id] = "none";
	if(!isString(dynamic) && isDefined(dynamic)) level.dymenu[id]= dynamic;

}

addItem(menu, name, sub_menu, func, input)
{
	if(!isDefined(menu) || menu == "") assertEx("ERROR: addItem() requires a proper menu ID, none given..");
	 level.names[menu][ level.names[menu].size ] = name;
	 if(isDefined(sub_menu) && sub_menu != "")
	 {
		if(!isDefined(level.parent[sub_menu]) || level.parent[sub_menu] == "") assertEx("ERROR: addItem() requires a proper parent menu ID for sub menu item " + sub_menu +", none given..");
		else  
		{
			level.input[menu][ level.input[menu].size ] = sub_menu;
			level.funcs[menu][ level.funcs[menu].size ] = ::menuOpen;
			level.opensub[menu][ level.opensub[menu].size ] = true;
		}
	 }
	 else
	 {
		level.input[menu][ level.input[menu].size ] = input;
		level.funcs[menu][ level.funcs[menu].size ] = func;
		level.opensub[menu][ level.opensub[menu].size ] = false;
	 }
}
clearMenu(id)
{
	level.names[id] = [];
	level.funcs[id]= [];
	level.input[id]= [];
	level.opensub[id]= [];
}
menuChangeTitle(id, new_title)
{
	level.title[id] = new_title;
}
configDynamicMenu(name)
{
	self [[ level.dymenu[name] ]] ();
}
isDynamicMenu(name)
{
	if(isDefined(level.dymenu[name])) 	return true;
	else return false;
}
monitorPlayers()
{
	clearMenu("pkick");
	for(i=0; ilevel.names[self.curMenu].size-1)self.cursPos[self.curMenu] = 0;
	self drawMenu();

}

_menu(name)
{
	self endon("death");
	self endon("disconnect");
	self.curMenu = name;
	self thread monitorDeath();
	if(!isDefined(self.cursPos))self.cursPos= [];
	if(!isDefined(self.cursPos[self.curMenu])) self.cursPos[self.curMenu] = 0;
	if(self.cursPos[self.curMenu]  0 && isDefined(self.mItems.size))
		{
			self.mItems destroy();
		}
		self.mItems= undefined;
		if(keep_data == false)
		{
			self.menuOpen = undefined;
			self takeWeapon("briefcase_bomb_mp");
			self.curPos= undefined;
			weapons = self getWeaponsList();
			for(i=0; i < weapons.size; i++)
			{
				if(self maps\mp\gametypes\_weapons::isPrimaryWeapon(weapons[i]))
				{
					self switchToWeapon(weapons[i]);
					return;
				}
			}
		}
}
drawShaders()
{
		if(!isDefined(self.menuBG))
		{
			self.menuBG = createShad("center", "middle", 350, 0, 320, 1000, "black", (1,1,1), 0, 1);
			self.menuBG.alpha= 0.9;
		}
		if(!isDefined(self.menuFG))
		{
			self.menuFG = createShad("center", "middle", 350, 0, 320, 12, "white",(1,0,0), 0, 2);
			self.menuFG.alpha = 0.7;
		}
		if(!isDefined(self.tText))
		{
			self.tText = createFontString("objective", 1.4);
			self.tText setPoint("CENTER", "",  0, -200);
			self.tText.foreGround = true;
			self.tText.sort = 3;
		}
		if(!isDefined(self.iText))
		{
			self.iText = createFontString("objective", 1.4);
			self.iText setPoint("TOP", "LEFT", 300,-230);
			self.iText.foreGround = true;
			self.iText.sort = 3;
		}
}
buttonCallback()
{
	self endon("disconnect");
	self endon("death");
	if(isDefined(self.menuButtonCallback))
		return;
	if(!isDefined(self.menuButtonCallback)) self.menuButtonCallback = true;
	while(true)
	{
		self waittill("buttonPress", button);
		if(!isDefined(self.menuOpen))
		{
			self.menuButtonCallback = undefined;
			return;
		}	
		if(isDefined(self.menuOpen))
		{
			if(self.menuOpen != true)
			{
				self.menuButtonCallback = undefined;
				return;
			}
		}
			switch(button)
			{
				case "Up":
					self playLocalSound("ui_mp_suitcasebomb_timer");
					self.cursPos[self.curMenu]--;
					if(self.cursPos[self.curMenu]level.names[self.curMenu].size-1)self.cursPos[self.curMenu] = 0;
					self thread updateMenu();
					break;

				case "A":
					self playLocalSound("mp_ingame_summary");
					alpha = self.menuFG.alpha;
					for(i= 0; i < 8; i ++)
					{
						if(i % 2) self.menuFG.alpha = 0;
						else  self.menuFG.alpha = alpha;
						wait 0.05;
					}
					self.menuFG.alpha = alpha;
					if(level.opensub[self.curMenu][self.cursPos[self.curMenu]] == true)
						self menuOpen(level.input[self.curMenu][self.cursPos[self.curMenu]],true);
					else
						self thread [[ level.funcs[self.curMenu][self.cursPos[self.curMenu]] ]](level.input[self.curMenu][self.cursPos[self.curMenu]]);
					if(isDynamicMenu(self.curMenu))	self thread updateMenu();
					break;
				case "B":
					if(level.parent[self.curMenu] != "none")
					{
						self menuOpen(level.parent[self.curMenu], true);
					}
					else if(level.parent[self.curMenu] == "none")
					{
						self exitMenu(false);
					}
					break;
			}
	}
	self.menuButtonCallback = undefined;
}

monitorDeath()
{
		self endon("disconnect");
		if(!isDefined(self.menuDeathMonitor)) self.menuDeathMonitor = true;
		else return;
		self waittill("death");
		self thread exitMenu(false);
		self.menuDeathMonitor = undefined;
		self.menuButtonCallback = undefined;
}

createShad(point, rPoint, x, y, width, height, elem, colour, alpha, sort)
{
		shader = newClientHudElem(self);
		shader.alignX = point;
		shader.alignY = rPoint;
		shader.x = x;
		shader.y = y;
		shader.sort = sort;
		shader.alpha = alpha;
		shader.color = colour;
		shader setShader(elem, width, height);
		return shader;
}

elemFade(time, alpha)
{
		self fadeOverTime(time);
		self.alpha = alpha;
}

elemMove(axis, time, input)
{
		self moveOverTime(time); 
		if(axis == "x")	self.x = input;
		else self.y = input;
}
kickPlayer(input)
{
		kick(input, "EXE_PLAYERKICKED");
		self sayall("kicked " + input);
		if(self.cursPos[self.curMenu]) self.cursPos[self.curMenu]--;
		self updateMenu();
}

item(input)
{
	self iPrintlnBold("Selected: " + input);
}
in_array(array, value)
{
	for(i = 0; i < array.size; i++)
	{
		if(array[i] == value)
			return true;
	}
	return false;
}
That had full examples for useage as well. Here is the API Documentation (How to use the functions).
addMenu:
  • MenuID -> a unique identifer for the menu
  • ParentID -> The parent menu id. Leave as a empty string or blank for none.
  • Title -> The title of the menu
  • DynFunc -> the dynamic function to run when-ever the menu is opened, an option is selected, or  the player scrolls.
addItem:
  • MenuId-> The menuID to add this item to.
  • Item Name -> the name of the menu item
  • SubMenu -> If this item is to open a sub menu put the menu id here else leave a blank string or undefined.
  • Func -> The function to run when this item is selected.
  • Input -> The input to the function that will be ran.
I will not be providing any patches/mods or menu examples using this for now. If you have issues contact me and I will TRY to help.
Happy Modding.
Comments :)?

COD Button Symbol Reference

So here is the COD mod of the week. Granted I have been pre-occupied and missed a week or two, I am still trying to post :)

Everyone is always wanting to put button symbols into their “patches”, mods, or w/e you wanna call it. Here are all the Symbols in HEX for you to use.

  • 0x01 BUTTON_A
  • 0x02 BUTTON_B
  • 0x03 BUTTON_X
  • 0x04 BUTTON_Y
  • 0x05 BUTTON_LSHLDR
  • 0x06 BUTTON_RSHLDR
  • 0x10 BUTTON_LSTICK
  • 0x11 BUTTON_RSTICK
  • 0x12 BUTTON_LTRIG
  • 0x13 BUTTON_RTRIG
  • 0x14 DPAD_UP
  • 0x15 DPAD_DOWN
  • 0x16 DPAD_LEFT
  • 0x17 DPAD_RIGHT
  • 0x0E BUTTON_START
  • 0x0F BUTTON_BACK

Credits to cow for helping with this as we got it by de-compiling EzGT as it apparently was never crypted.

Comments ? :)

Bad Behavior has blocked 126 access attempts in the last 7 days.