You are on page 1of 125

Comprehensive User Guide

Introduction

vbGOREmania is based on vbGORE, a powerful, open source, and free online RPG engine. With this
engine you can create an impressive 2D MMORPG (Massively Multiplayer Online Role-Playing
Game)! It is simply a collection of add-ons, tweaks, upgrades, and more made by me (GOREmania)
and others of the vbGORE community. vbGORE is not my creation, and this is not the official
vbGORE website nor is it a replacement. This Guide is a compilation of the vbGORE wiki and
vbGOREmania features.

Help Topics

Editors And Tools Game Engine General Info


• Map Editor • Features • Control Panel
• Particle Editor • Installing • Adding NPCs
• House Editor • Game Client • Adding NPC AIs
• Job Editor • Game Server • Adding Items
• NPC Editor • Update Server/Client • Adding Graphics
• NPC Chat Editor • Database • Adding Quests
• Object/Item Editor • Publish Your Game • Adding Signs
• Quest Editor • Adding Skills
• Skill (Spells) Editor • Useful Links
• Color Selector
• File Processor
• Free Number Finder
• Log Remover
• Grh Categorizer
• Grh Dat Maker
• Grh Raw Assistant

Return To Help Topics


Editors And Tools

Map Editor

This is the main window for the map editor. One of the most important things to point out is the tool
icon bar, shown below:

Display Buttons
The following buttons can turn on or off certain layers and objects to be displayed.

Hide/Show Weather

Return To Help Topics


Hide/Show NPCs

Turn On/Off Bright Mode

Hide/Show 32x32 Grid

Hide/Show Tile Info

Hide/Show Mini Map

File Buttons
Optimize: Cleans up the map to speed it up and reduce size

Load: Loads a previously saved map

Save: Saves the current map

Save As: Save the current map in a new number

New: Opens a new map

Search Bar

The Search Bar is found on the bottom of the map editor screen. The search bar cannot be moved or
altered. It is used to help you search for a tile you need:

Return To Help Topics


1: This is where you input the search details
2: Here you choose which type of search you would like to do. After you have typed something into the
search bar and selected what type of search you would like to do, press search and it will find
something that matches your search.

Grh Index
- This will search through all the tiles in the grh index to find one with a number that matches
your search.

File Number
- This will search through the file numbers to find the tile that you are looking for.

Description
- This will give you a description of what you are searching for.

If you do a search for 49 and select Grh Index, then click search, something like this will display:

It is texture 9, but if you click on the 4th one over, you can see the grh number is 49.

Tile Select List

By clicking the view sheet button located on the bottom of the map editor screen and to the right of the
search bar will bring up the following screen:

Return To Help Topics


In this window if you right click it will bring up a few options:

Start Number
This number represents the number of the tile you wish to start with from the list of tiles, this will
be very helpful if you have thousands of tiles. For example, if you would like to start with tile
number 673, you can type that into the start number line, and the list of tiles will be from 673 to
all the tiles after that.

Preview Size
Setting the width/height allows you to define how wide/tall you want to have the tile preview
drawn. This is useful so that you can tell which of your tiles are 32x32 and which are
bigger(whole trees and things).

Show Options
These check boxes allow you to pick and choose which tiles you would like to look at among the
large list of tiles. If you check only outside objects and click save changes it will show you just
the tiles used for outside. You can also use the start number to narrow the tiles down a bit more
too. If you were to put the start number at 673, and click the outside object box only, it will show
tiles for the outside starting from tile number 673.

Select Tile From PNG

By clicking the “Select From PNG” button located on the bottom of the map editor screen and to the
right of the search bar will bring up the following screen:

Return To Help Topics


In this window you can open a particular PNG texture file by clicking the browse button at the top.
Once you open a PNG, the dimensions of image are displayed at the top right of the window. In that
area you will see a checkbox called “Grid” which lets you render a 30x30 grid over the image. On the
far left side of the window you will see a list. This is a list of Grhs that are associated with the PNG. If
you click on one, the Grh will be highlighted in yellow in the image on the right hand side. When you
have found the Grh you want, and have selected it in the Grh list, minimize the window. You will see
that you are all set to start placing your tile on the map!

Set Tiles

The 'Set tiles' button is the sixth button from the left
Click this to bring up the Set Tiles window, as shown below:

Return To Help Topics


1 - Layer Section
Number 1 is showing the layer selection. There are 6 layers that vbGORE uses for the maps. The
first three layers are drawn under the player. The 4th through 6th layers are drawn above.

2 – Hide/Show Layers
Number 2 is pointing to checkboxes beneath the Layer Section. When a checkbox is checked,
the associated layer will be rendered (shown) on the map editor, else it is hidden. This is useful if
you want to see something that is hidden by the layer above.

3 - Grh Set Checkbox


Number 3 is pointing to the box that you check to be able to place a tile onto the map. Once the
box is checked and you select the tile you would like to use, you can just click on the map where
you would like to place it and it will be placed there. If you then decide that you would like to
remove a tile, you can just hold ctrl and right click.

4 - Light Set Checkbox


Number 4 is for the light value. This value allows a tile to be drawn differently then it is colored.
For instance: if you have a tile that is bright and cheerful but you wish to use it in a dark and
sinister way, you can check this box and set a custom value that will have the tile be drawn darker
or even a completely different color(works best with a image done in grey scale) without having
to make a completely different tile.

5 - Light Values
This is set up to where you can change the light for each of the corners. Number 5 points to the
four values to change. Be warned though, if the light check box is not checked your tile will be
drawn without the custom light value. These values are ARGB (Alpha Red Green Blue) values.
Alpha is the transparency of the light, where 255 is opaque and 0 is invisible. To get this value,
either click the ARGB <-> Long Tool button on the bottom of the map editor, or use the
ToolColorCon program that comes with vbGORE.

6 - Shadows
Number 6 is the check box for shadows and a value you need to set(Probably done this way so
you do not need to replace the tile if you want to just turn off the shadow). Set the value to 1 to
set the shadow and 0 to allow you to take it off.

Return To Help Topics


7 - Grh number
Number 7 is where we type the number of the tile we wish to use. Just type the number of the grh
that you would like to use in that box.

It is also good to note that when you are setting Grhs on a map, the tile your mouse hovers over will be
highlighted. This will help you know what you are actually selecting.

Blocked Tiles

Clicking this button will bring up the following window:

This window is simple in that you use it to set whether the tile is blocked for moving/ranged attacks or
not.
Checking the "Set walk" Checkbox allows you to make tiles blocked or not. Choose the direction or
directions that you wish the player to not be able to move(center check box for all directions) and then
start clicking where you want blocked.
Checking the "Set Attack" Checkbox allows you to make tiles block attacks or not. Once checked, a
new "No Attack" checkbox appears on the bottom right of the window. Checking this makes which tile
you click block attacks.
You may use movement/attack block set both at once.
Also, you may check the “Reflective” checkbox to make the selected tile reflective. When the player
stands on such a tile, their reflection appears just below them.

Map Floods

This button is used to flood the map with certain things. It combos with the first button and others to
allow you to flood a single layer or more using whatever tile/light/etc. settings you choose.

Return To Help Topics


When clicked, the following window will be brought up:

Map
If you choose a grh and click map, it will flood the entire map with the grh.

Screen
If you choose a Grh and click screen, it will flood just the area where your screen was.

When you click one of these options it will bring up a box that asks you if you are sure that you want to
flood the map. It will show you what options you have selected. These options are set from the other
windows. Note that this uses the same actions as the normal tile set, which means the other windows
must be opened to be used.

Return To Help Topics


Set NPCs
Probably not good to have an NPC set to set on every tile on the map.
Erase NPCs
Useful to clear the map of all NPC's.
Set OBJs
Flood the map with items.
Erase OBjs
Clears any object. Useful for clearing the map of all objects.
Set Tiles
This is the most common one you would be using the flood for. You can use flood to set all tiles
to 0 or for grass, etc. Basically mass changes.

Tile Information

The next button is the tile info button. Clicking this button will bring up the following window:

This window shows info on tiles. Right click a tile to see the information displayed here. Easy changes
can by typed into the fields if desired. Currently, the only way to set mailbox/sign flags is through this
window - just enter a 1 into the mailbox/sign field to place the mailbox/sign, and a 0 to remove it. For
convenience, the button next to Signs will open a window with a list of all signs and their descriptions.
For example:

Return To Help Topics


Exits

This next button is the exits button. Clicking this button will bring up the following window:

This button allows you to setup an exit by using the following fields:
Map
This is the number of the map that the exit leads to. It can be either the same map, or another one.
X/Y
This is the coordinate of where the exit leads to.

Return To Help Topics


The section of this window titled “Apply to entire” will let you set the warp to the entire left, right, top,
and/or bottom edge of the map. You can optionally keep the player's X and/or Y upon warping. So if
you apply a warp to the entire left border of the map and check “Keep Player's Y,” then the player will
warp to the appropriate map to the specified coordinate, but the Y coordinate from the previous map
will be kept.
i.e. Warp from map 1 from coordinate 2, 1 to map 2, coordinate 30, 1. Notice the Y (1) stayed the
same.
This feature is a time saver when it comes to setting warps from one are to another.

NPC Window

Next button is the NPCs button . Clicking this button will bring up the following window:

This shows all npc's you have for your game. Just choose either to place/erase from the tiles(s) you
later select.

NOTE
It is good to note now that you should uncheck or close the “Set Tile” window when setting NPCs, and
vice versa, so that you are not both setting tiles and NPCs.

Particle Effects Window

Next is the Particles button, Clicking this button will bring up the following window:

Return To Help Topics


This window is used to set up map-bound particle effects. These effects will "stick" to the map and be
displayed on everyone's screen. Note that the effects all look different for every client - they run off the
same equation, but how the equation pans out is often randomized thus resulting in different views. In
most instances, this wont be a problem or even noticeable. This is how you setup an effect like the
waterfall from the demo map.
ID
Is the ID of the particle effect used. This number is the same number as the constants with the
EffectNum_ prefix in the declarations section of the Particles module. For example, 1 is fire and
9 is the waterfall.

Gfx
Is the texture used for the particle. In the \Grh\ folder, the files with the prefix p stand for a
particle texture. For example, 10 will use p10.png, the skulls, and p3 will use p3.png, the ankh.

X and Y
Are the absolute pixel positions of the effect. The values defined in here are the amount of pixels
away from the top-left corner of the map. You can see this value when moving your cursor over
the screen in the map editor.

Particles
States how many particles are used. The amount you want to use depends greatly on the particle
effect - how dense you want it, what kind of graphic it is using, how large of an area it covers,
etc. Try to keep the number under 1000, though, or you may notice a bit of hit to performance.

Dir
Or Direction, is an optional parameter. Some effects use a Direction value to state which way
they are animating, such as the fire. Whether this is used or not depends completely on how the
effect is written. It is easiest to see if this is used by a certain effect by if it is used in the
Effect_Begin sub in the Effects module. The value is always saved, but not always used.

Return To Help Topics


Because particles can be a bit tricky to set up, an Edit Mode is available. You can tick the box named
Edit Mode on the effects screen to edit the effect you have high-lighted. If Edit Mode is ticked, and you
change the values in the text boxes, the high-lighted effect's value will change. If not in Edit Mode,
though, the high-lighted effect wont change. This is to allow you to enter values and press the Create
button without worrying about messing up old effects.
Whether in Edit Mode or not, all effects can be moved by high-lighting them, then holding Shift +
Right Clicking on the game screen. The effect will then be moved to the location you clicked on the
screen
Once you have everything typed in, click create.

Sound Effects

Next is the Sound Effects button, Clicking this button will bring up the following window:

Each sound effect is setup with a number. Just type it in and click the tile you want it to be on.

Map Information

Next is the Map Info button. Clicking this button will bring up the following window:

Return To Help Topics


Map Name
Is of course the name of the map.
Version number
Just a version number, change it if you update, if you want
Weather
Choose the weather for the map. Currently there is 0 for none, 1 for snow, and 2 for rain. You
can have up to three different types of weather per map. The engine will randomly change from
one to another of these weather types you select.
Music
Background music for the map, setup using a number assigned to it.

Is Property
This is used for player housing/property. It just means that the player can buy this map as a
property. You have to have at least one NPC on this map with the Servant AI if you set the map as a
Property. More info will be provided later for how to setup player housing.

Can Set Respawn


This option will let players set their respawn point on this map.

Walkthrough Players/NPCs
These options let players and NPCs walk through each other. It is good to have this option
selected on maps where there may be a lot of people. Though, making it so players can't pass through
each other or through NPCs is good if you want to make escape from battle hard!

Return To Help Topics


Class/Level Requirement
These options are used to set the class or level requirements to access a map. For example, you
may only want level 60 wizards to access the Master Wizard Guild you just created!

Particle Editor

This editor will let you create awesome new particle effects for your game. This aspect of the game
design can be a challenge, but this editor helps make it easier. First thing to note are the Inputs:

I suggest just try putting various values in to see what happens.


Effect will let you select the particle effect design
Gfx will let you change the particle shape.
Particles is the number of particles in the effect. S
Size is the size of the particles
Time is the duration of the effect
Alpha is the transparency of the particles. (-1 for random)
Red, Green, and Blue are the levels of these colors in each particle. (-1 for random)

Return To Help Topics


When you are finished, copy the code at the bottom of the editor and paste into the game! That's it!

Adding New Effect Designs (Advanced!)


This next part is for the truly advanced out there. What you can do is add new equations to the editor
for more awesome effects. Example Equations can be found at
http://vbgore.com/Particle_effect_equations

First off add a new constant for your Effect at the top of Particles.bas. Example:
Public Const EffectNum_Wormhole As Byte = 24

Then go to Effect_UpdateAll and add the required code that will update your effect's animation:
If Effect(LoopC).EffectNum = EffectNum_Waterfall Then Effect_Waterfall_Update LoopC

Then go to Effect_Spawn_Reset and add your effect equation:


Case EffectNum_Wormhole
Effect(EffectIndex).Progression = Effect(EffectIndex).Progression + 0.1
R = (Index / 20) * Exp(Index / Effect(EffectIndex).Progression Mod 3)
X = R * Cos(Index)
Y = R * Sin(Index)

'Determine if deafults are used


If Red = -1 Then Red = 1
If Green = -1 Then Green = 1
If Blue = -1 Then Blue = 1
If Alpha = -1 Then Alpha = 1

'Reset the particle


Effect(EffectIndex).Particles(Index).ResetIt Effect(EffectIndex).X + X, Effect(EffectIndex).Y + Y, 0, 0, 0, 0
Effect(EffectIndex).Particles(Index).ResetColor Red, Green, Blue, Alpha, 0.2 + (Rnd * 0.2)

Then in frmMain.frm, you need to add your effect to the combobox so you can modify it with the
editor:
Case 17
DispEffect = Effect_Spawn_Begin(EffectNum_Wormhole, ResetX, ResetY, cmbGfx.ListIndex + 1,
Val(txtParticles.Text), Val(TxtSize.Text), Val(txtTime.Text), Val(txtRed.Text), Val(txtGreen.Text), Val(txtBlue.Text),
Val(txtAlpha.Text))

Return To Help Topics


txtFormula.Text = "Effect_Spawn_Begin(EffectNum_Wormhole, X, Y, " & (cmbGfx.ListIndex + 1) & ", " &
Val(txtParticles.Text) & ", " & Val(TxtSize.Text) & ", " & Val(txtTime.Text) & ", " & Val(txtRed.Text) & ", " &
Val(txtGreen.Text) & ", " & Val(txtBlue.Text) & ", " & Val(txtAlpha.Text) & ")"

House Editor

The housing editor is used set up maps as property (Player Houses). To set up a new property, click
new. Enter the map number, property value, and warp (x,y) coordinate for where the player enters
when using house teleport. When done, press “Save,” and move on to Step 2.
When you want to remove a property, select it from the list on the left and press Delete, then move on
to Step 2.
To Edit an existing property, select it from the list and change the appropriate values and press Save.
Take note of what Step 2 says. After you set up a map as a property via this editor, you have to use the
map editor and proceed to the Map Info window and select the “Property” Checkbox. You also have to
have an NPC with the Servant AI on this map.
Servants
servants allow a player to put up items for sale and to set a Premium (5-15%) on items they sell. For
example, an item with a value of 100 sold at a premium of 5% will sell for 105 (100 + (100 * 0.5)).
It is through the servant that players can buy/sell the property. When a player sells a property, they get
back 75% of its value. When someone buys from the store, the owner gets the money added to their
bank! Players can also talk to the servant to Rest at the map (as you would at an Inn), and restore hp
and mp.
Due to how the store script works, the Store Menu will not open unless there's an item in there. And

Return To Help Topics


due to some other inherit "features," I made it add a default worthless item to the store when it is empty
(the tiny healing potion, which I gave a price of 1 in the database).
Furniture
The way it works is that the user clicks on the furniture in their inventory. That item is removed from
their inventory and a new NPC (specified by the NPC_Spawn field of the object) is added to the map
representing the furniture. When the user clicks on the furniture NPC, the NPC is removed and the item
(specified in the drop field) is added to the user's inventory. When adding furniture, the furniture will
face the same direction as the player.
Furniture NPCs and Items can be created through the NPC Editor and Object Editor.
Ownership:
Players can only own one property. Only the owner can add/remove furniture to a property. And only
the owner can add/remove items from the store (without paying for it).

Job Editor

There are three types of job skills: Blacksmith, Alchemy, and Crafting. Job skills are used to make
items. Blacksmiths can make weapons, armor, shields, etc. Crafting is used to make bows, furniture,
etc. Alchemy is used to make potions. All the jobs have the following common properties:
Name: The name of the item to be made.
Level: The level of the appropriate skill required to make the item.
XP: The amount of experience to be gained from making the item.
Index: The slot in the job menu the item is. (Shown Below)
Page: The page of the menu the item is located on. Each menu has three pages.

Return To Help Topics


Blacksmith (Items)

The index count for metals is 1-7 for each page.


The index count for items proceeds as normal for each page
Blacksmith (Metals)

There is only one page for this menu


Alchemy

Crafting

Note: One page two and page three, the index continues as shown above, starting the next number
from where the count left off.

Return To Help Topics


Now each job skill has some differences:
Blacksmith (Metals)
Ore: The material used to make the item
Bar: The Item to be made

Blacksmith (Items)
Item: The item to be made
Metal: The material (Metal bar) to be used to make the item
Amount: The amount of metal to be used to make the item

Alchemy Potions
Potion: The item to be made
Herb: The material (herb) to be used to make the item
Amount: The amount of herbs to be used to make the item

Craft Items
Product: The item to be made
Material: The material (herb) to be used to make the item
Amount: The amount of herbs to be used to make the item

When you are done inputing the details for your new item, hit the appropriate Create button. Step by
step instructions will then appear with details on how to add the new item to the job menu and into the
game.

Return To Help Topics


NPC Editor

This editor serves to help you add, edit, and delete NPCs in an easy to follow layout, rather than having
to edit the Database. All existing NPCs are shown in the list on the left. Click on an NPC to edit it.
ID: The id of the NPC. It must be unique. In the editor, this field is only visible while editing an
existing NPC
Name: The name of your NPC.
Description: This is the NPC's description. It is shown in your ingame chatbox when you right click on
the NPC.
AI: This decides what your NPC does. To add your own type of AI or see the available ones you need
to open GameServer.vbp in vbGORE folder and find
Public Sub NPC_AI(ByVal NPCIndex As Integer)

located in the NPCS module. The number you put in the database will correspond to the Case found in
that method.
Job: This only matters if the AI is set to 10, which refers to a Job NPC such as an Anvil, Furnace, etc.
1. Job Menu
2. Anvil
3. Alchemy Table
4. Craft Table

Return To Help Topics


NPC Chat: What the NPC says. This can be found in
vbGore folder >> Data >> NPC chat >> 'yourgamelanguage'.ini

Quest: The ID of the quest that the NPC gives, 0 = No quest. Quests can be found in the Database
under Quest Table. This editor conveniently displays the list of existing quests.
Hair: What hair ID the NPC will have. This can be found in
vbGORE folder >> Data >> Hair.dat

Head: What head ID the NPC will have. This can be found in
vbGORE folder >> Data >> Head.dat

Nody: What body ID the NPC will have. This can be found in
vbGORE folder >> Data >> Body.dat

Weapon: What weapon ID the NPC will have. This can be found in
vbGORE folder >> Data >> Weapon.dat

Wings: What wing ID the NPC will have. This can be found in
vbGORE folder >> Data >> Wing.dat

Heading: Decides what direction the NPC is turned when it spawns.


Head Heading: The heading of the NPCs head when it spawns.

Shop: This decides whether the NPC is a shop or not. Leaving it empty means its not a shop. The
format is as followed
ITEMID PRICE

Example
1 500

The NPC sells the ID 1 item for 500 gold.


Note: Below the shop text area, you will see “Item” and “Amount.” Select an item from the drop
down and enter the price and then click “+” button to add an item to the shop.
Elemental Bonuses: Enter values for Air, Earth, Water, and Fire for the elemental bonuses the item
gives.
Combat Level: The NPC's combat level, which is displayed next to their name above the NPC. If you
are unsure what to put here, you can click “Suggest Level” for a recommended level based on the
combat stats. Some NPCs wont display a level (like a shop owner or a job NPC such as a furnace;
which is determined by the AI).
Attackable: Decides whether its possible to attack the NPC or not.

Return To Help Topics


Attack Grh: What attack GRH to show whenever the NPC attacks something.
Attack Sfx: Which sound affect to play when the NPC attacks. The sound affects can be found in the
Sfx folder of vbGORE.
Respawn Wait: This is the amount of time it takes for the NPC to respawn after it has died. The
amount is in milliseconds.
1 Second = 1,000
10 Seconds = 10,000.

The formula is second*1000.


Range: Can the NPC attack from a distance? 0 ~ melee (close), 1 ~ Range (long range attack)
Rotate Speed: If the NPC's attack is ranged then this will decide at what speed it will rotate.
Hostile: Decides whether the NPC is hostile or not (If it attacks players or not).
Experience Points: The amount of XP the player will receive when the NPC is killed.
Give Gold: The amount of gold the player will receive when the NPC is killed.
drops: What items the NPC will drop. The format is as followed
ITEMID AMOUNTTODROP %CHANCEOFDROPPING

Example
5 10 98

The NPC can drop 10, ID 5 items with a 98% chance.


Note: below the “Drops” text area, there are comboboxes for “Item,” “Amount,” and “Probability.”
Insert the desired values and click the “+” button to add a new drop. This is just an alternate method to
add drop items, rather than the manual method explained above.
Hit Rate: The attack speed of the NPC.
Magic: The magic stat of the NPC.
Defense: The defence stat of the NPC.
Speed: The speed stat of the NPC.
Hit Min: The minimum damage the NPC can hit (close range attack).
Hit Max: The maximum damage the NPC can hit (close range attack).
Range Min: The minimum damage the NPC can hit with a long distance attack.
Range Max: The maximum damage the NPC can hit with a long distance attack.
HP: The amount of HP the NPC spawns with.
MP: The amount of MP the NPC spawns with.
SP: The amount of SP the NPC spawns with.

Return To Help Topics


TIPS ON ADDING NPCS:
Player Housing Related:
• Adding Servants: Fill out the information for the NPC as you wish, but...
◦ use the Servant AI, which is 8
• Adding Furniture: Fill out the information for the NPC as you wish, but...
◦ Use the Furniture AI, which is 9
◦ Add one Drop Item
▪ @ 1 100 (where @ is corresponding furniture object/item; the other 2 values are
amount and drop rate. keep them as they are)
◦ Hair: The number corresponding to the furniture paperdoll, stored in hair.dat file
◦ Head: 0
◦ Body: 0

Furniture Basics:
The way it works is that the user clicks on the furniture in their inventory. That item is removed from
their inventory and a new NPC (specified by the NPC_Spawn field of the object) is added to the map
representing the furniture. When the user clicks on the furniture NPC, the NPC is removed and the item
(specified in the Drop field) is added to the user's inventory.
Furniture NPCs sprites are stored in the Hair.dat file. Everything is labeled so you know. Basically
when a furniture NPC is spawned on the map, it is just the Hair item (no body or head). This was done
this way to save creating extra *.dat files and fields in the database.

Animals And Creatures


Animals/Creatures that are a single paperdoll layer (such as the Golem in the Demo) are stored in the
body.dat file. They are labeled for easy finding. This is was done to save from creating extra dat files
and fields in the database. You don't have to do your animals or creatures this way. But if you have
creatures with a body/head that are not used by other NPCs/Players, then it may be best to do it this
way.

Job NPCs
Job NPCs sprites (i.e. Anvils) are stored in the Hair.dat file. Everything is labeled so you know.
Basically when a furniture NPC is spawned on the map, it is just the Hair item. This was done this way
to save creating extra dat files and fields in the database.
Jobs are activated by clicking on the job NPC instance (i.e. furnace, anvil, craft table, or alchemy
table).

Return To Help Topics


NPC Chat Editor
This editor will help you edit the chat files with greater ease. NPC chats are a difficult hurdle for
vbGORE game developers, but it not so bad once you get the hang of it.

One the left-hand side of the editor, you will see a list of all NPC chats in the file you are editing. To
change which language file you are editing, select the appropriate language from the “Language”
combobox at the top of the editor. Also at the top of the editor are three other comboboxes:
Condition: This defines when the chat will take place. One of each condition may be used for each
line. If you do not define a condition for each line, the last used condition for the current chat ID is
used. If you do not define a condition at all, no conditions will be required.
• !CLEAR - Clears all the conditions. You MUST use this if you want to get rid of previous
conditions!
• !SAY x - The chat will only be said if the user types a message that contains the text X. X can
be broken into multiple statements separated by commas. Underscores must be made where
spaces are required!
◦ IE: !SAY test,_test_,_test,test_
◦ Enter [EMPTY] for text to say nothing but still use the delay (mainly used for the
RANDOM).
• !LEVELLESSTHAN x - The user's level must be <= X.
• !LEVELMORETHAN x - The user's level must be >= X.

Return To Help Topics


• !HPLESSTHAN x - The NPC's level must be <= X %.
• !HPMORETHAN x - The NPC's hp must be >= X %.
• !KNOWSKILL x - The user knows skill X (SkID value).
• !DONTKNOWSKILL x - The user doesn't know skill X.
Styles: The way the NPC's message displays
• BUBBLE - Displays the chat only in the chat bubble.
• BOX - Displays the chat only in the chat box.
• BOTH - Displays the chat in both the chat bubble and box.
Formats: The chat format defines how the chat is handled. You can not change the format in the
middle of the routine, nor define more then one per routine. Each format must follow their own specific
formatting rules.
• RANDOM - Randomly use a line of chat. The WAIT value is only used once, and must be
defined right after the <>. The wait defines how long between each message.
• LINEAR - Goes through the lines, one by one, in order. A WAIT must be used after each SAY.
The wait defines how long after the previous message the new message will be.

These three comboboxes are simply there to help you remember and insert commands faster, and the
Chat Library on the left is only to help you locate Chat Ids faster. Selecting an option from these
comboboxes and then clicking the “+” button next to them will insert the selected option, i.e. !CLEAR,
to where the cursor is in the chat file. This editor will not write your NPC messages for you. You still
need to be familiar how to format your commands and messages. See below for more information.
Commands:
• BEGINFILE - States that from this marker and on, there is actually going to be data. Keep your
header text, and only your header text above this.
• [x] - Holds the chat ID to be used, where "x" is the ID.
• !x - Holds the conditions required for the chat to start.
• FORMAT x - Holds the chat type, where "x" is the format.
• STYLE x - Forces all the following lines of chat to use the defined chat style, "x".
• SAY x y - Says a message with the text "y" then waits x milliseconds after saying that text.
• Also know that you can add line breaks to SAY and ASK lines with /r

Examples:
[1]
FORMAT RANDOM

Return To Help Topics


STYLE BUBBLE
SAY 5000 This is a chat test! I appear in the bubble only!

STYLE BOX
SAY 5000 This is a chat test! I appear in the box only!

STYLE BOTH
SAY 5000 This is a chat test! I appear in the box and bubble!

[2]
FORMAT LINEAR
STYLE BUBBLE
!HPLESSTHAN 50

SAY 5000 This message will only appear when your HP is less than 50%!
SAY 5000 And so will this one!

!HPMORETHAN 50
SAY 5000 HP <= 50 and HP >= 50 is applied, so this will only appear is HP is exactly 50%!

!CLEAR
SAY 5000 This will appear no matter what!
SAY 5000 So does this!
SAY 5000 Conditions carry on linearly - so until a !CLEAR is reached, or a new index is acquired, the
conditions stay!

[5]
FORMAT LINEAR
STYLE BUBBLE

SAY 5000 You can put the any index anywhere you want! Though it is best to put them in order, or else
SAY 5000 you can easily loose track of some indexes! It is best to NEVER skip an index, or else you

Return To Help Topics


are wasting RAM and CPU!

[3]
FORMAT LINEAR
STYLE BOTH
!LEVELLESSTHAN 5
!HPLESSTHAN 50
!DONTKNOWSKILL 1
!LEVELMORETHAN 5
!HPMORETHAN 50
!KNOWSKILL 3

SAY 5000 You can apply as many conditions as you wish! Though make sure you use !CLEAR when
you want to remove some!

[4]
FORMAT LINEAR
STYLE BOTH

SAY 5000 This appears no matter what, even though theres no conditions! !CLEAR is automatically
called when a new index (the [4]) is gathered!

Object/Item Editor
Items are handled in vbGORE server-side on the database. It is then up to the server to send data to the
client on items. This, though, just covers how to actually add items, which is a very easy process. You
can either edit existing items, add new items, or delete existing items. The Object Editor makes
adding items a breeze!
On the left hand side of the editor is a list of all items in the database. You can select from this list to
edit/delete an item, or you can create a new item by clicking on “New.”

Return To Help Topics


Id: The unique id of the Quest - you can only have 1 of each ID.
Name: The item name.
Description: Brief description of the item.
Price: The price of the item. This can be used in stores to buy or sell items.
Objtype: What type of item it is
1. Consumable
2. Weapon
3. Armor
4. Wing
5. Infinite (Like consumable but can be reused infinitely)
6. Shield
7. Mount
8. Furniture
9. Helmet

Return To Help Topics


Weapon Type: How far the weapon can hit.
1. Hand = 0 'Weapon is hand-based
2. Staff = 1 'Weapon is a staff
3. Dagger = 2 'Weapon is a dagger
4. Sword = 3 'Weapon is a sword
5. Throwing = 4 'Weapon is thrown (ninja stars, throwing knives, etc)
Weapon Range: How far the weapon can hit.
Projectile Rotate Speed: How fast a projectile rotates when in action (useful for ninja stars and similar
items).
Limit To Class: If the item has a class requirement, put the class ID in here.
Grh Index: The item graphic.
Use Grh: What grh to show when being used.
Use Sfx: Sound affect when used.
stacking: If the item can stack (This is if more than 1 of the same items can be held in one item slot)
-1 = Server's default limit
1 = Not stackable
>1 = Stackable by this value

NPC Spawn: Index of NPC to spawn. Used for Furniture objects. When furniture is used (placed on
board), the item is removed from inventory and an NPC is created on the board.
Body: What body ID to change the body to if the item is used. The body ID can be found at
vbGORE folder >> Data >> Body.dat

Weapon: What weapon ID to show if the item is used. The weapon ID can be found at
vbGORE folder >> Data >> Weapon.dat

Hair: What hair ID to show on the character if the item is used. The hair ID can be found at
vbGORE folder >> Data >> Hair.dat

Head: What head ID to show on the character if the item is used. The head ID can be found at
vbGORE folder >> Data >> Head.dat

Wings: What wings ID to show on the character if the item is used. The wings ID can be found at
vbGORE folder >> Data >> Wings.dat

Mount: What mount ID to show on the character if item is used. The mount ID can be found at
vbGORE folder >> Data >> Mount.dat

Return To Help Topics


Shield: What shield ID to show on the character if the item is used. The wings ID can be found at

vbGORE folder >> Data >> Shield.dat

Elemental Bonuses: The amount of the element bonus (Air, Earth, Fire Water) object gives when
equipped

Replenish Hp: How much HP the character will replenish when the item is used.

Replenish Mp: How much MP the character will replenish when the item is used.
Replenish Sp: How much SP the character will replenish when the item is used.
Replenish Hp Percent: How many % of HP the character will replenish when the item is used.
Replenish Mp Percent: How many % of MP the character will replenish when the item is used.
Replenish Sp Percent: How many % of SP the character will replenish when the item is used.
Stats: How much of the stat (strength, HP, SP, Speed, Agility, etc) the object gives when equipped
Requirements: How much of the stat (Combat Level, Strength, Agility, and Magic) is required for the
use of the item.

Adding Furniture Object


• Fill out the Name, Price, etc as usual
• Set the object type to 8
• Set the Grh index to the graphic that will be seen when the object is in the inventory
• Set NPC Spawn to the index of the NPC that will be placed on the map to represent the
furniture.

Furniture Basics:
The way it works is that the user clicks on the furniture in their inventory. That item is removed from
their inventory and a new NPC (specified by the NPC_Spawn field of the object) is added to the map
representing the furniture. When the user clicks on the furniture NPC, the NPC is removed and the item
(specified in the drop field) is added to the user's inventory. When placing furniture down in the house,
the furniture will face the same direction as the player.

Player Housing Furniture Items spawn Furniture NPCs and vice versa. The Item added to a player's
inventory when picking up furniture is indicated in the NPC's drop field in the database. NPCs
spawned when users click on Furniture Items in their inventory is stored in the NPC_Spawn field of the
object table in the database.

Items and Furniture NPCs sprites are stored in the Hair.dat file. Everything is labeled so you know.
Basically when a furniture NPC is spawned on the map, it is just the Hair item. This was done this way
to save creating extra dat files and fields in the database.

Return To Help Topics


Quest Editor

The Quest Editor is used to help you quickly add/edit/delete quests. On the left side of the editor is a
list of all quests. You can select one to edit or delete. You may add a new quest by clicking the “New”
button.

Id: The unique id of the Quest - you can only have 1 of each ID.
Name: The quest name.
Redo-able: Whether the player can do the quest more than once
Start Text: This is what the NPC who starts the quest says when you right click him.
Accept Text: This is what the NPC who gives the quest says after you accept it.
Quest Incomplete: This is what the NPC who gives the quest says when you talk to it while not having
finished the quest yet.
Finish Text: What the NPC who gives the quest says when you return with the quest finished.
Quest Description: The description of the quest. It appears on the client quest screen.

Rewards Upon Accepting:


Experience Points: Amount of XP player receives for accepting the quest.

Return To Help Topics


Gold Reward: Amount of Gold the player receives for accepting the quest.
Reward Object: The object the player receives for accepting the quest (Object ID).
Reward Object Amount: The amount of objects the player receives for accepting the quest.
Skill Reward: What skill is taught to the player when quest is accepted. (Skill ID)

Rewards Upon Completion:


Experience Points: Amount of XP gained when quest is finished.
Gold Reward: Amount of Gold the player receives for finishing the quest.
Reward Object: What Item is received when the quest is finished.
Reward Object Amount: The amount of objects received when the quest is finished.
Skill Reward: What skill is learned when the quest is finished.

Requirements to Accept
Required Level: The level your character has to be to be able to accept the quest.
Required Object: The object your character must have to be able to accept the quest.
Required object Amount: The amout of required objects your player must have to accept the quest.
Prerequisite: The quest your player must have already finished to accept this quest.

Requirements To Finish
Required Object: The object the player must have when finishing the quest.
Required Object Amount: The amount of required objects the player must have to complete the quest.
Kill NPC: What NPC must be killed to finish the quest.
Kill NPC Amount: The amount of required NPCs must be killed the finish the quest.

Skill (Spells) Editor & Adding Skills


There are two ways to add skills. The first way is with the skill editor. This will let you create,
customize, and add a new skill to your game. This method, however, is limited in what it can do.
Should you want to add a new skill that does something not covered by the skill editor, then you must
code it yourself. Hard-coded spells will let you do what ever you want to do. The problem that comes
with this, though, is difficulty.

Return To Help Topics


Skill Editor

Name: The name of the skill


Skill Grh: The Graphic used when the skill is equipped to the quickbar
Sound FX: The sound effect when the skill is used.
Skill Length: The length of time the skill lasts (mostly used with buffs)
Skill Exhaust: How long the player must wait before the next skill can be used.
Effect: What the skill will do
• Adjust Stats: Affects the target's various stats (Strength, Defense, HP, etc) for a length of time
(i.e. Buffs, poison, etc)
• Summon NPC: Summon an NPC
• Teleport: Teleport the caster to a specific location
• Transform: Transforms the caster into a specific creature
◦ Replaces the user's body, head, weapon, etc with a single body Grh. (i.e. a Golem)
◦ The caster also gains a boost in their stats while transformed (which you customize)

Note: The other textboxes will be enabled/disabled depending on which effect you are using. For
example, if you are creating a teleport skill, Body Index will be disabled since that has no relevance.

Return To Help Topics


Body Index: The body graphic (see data/Body.dat) to use for the transformation skill
Mana Cost: The amount of MP consumed to cast the skill.
HP Cost: The HP lost when the spell is cast.
Teleport Map/x/y: The coordinate to teleport to
Teleport Effect: The number corresponding to the particle effect displayed when the teleport skill is
used.
Display Icon: If checked, the selected Spell Icon will be displayed above the caster's head
Summon NPC: The NPC to summon
Lasts Over Time: Check this if you wish the spell to last over time (as with poison)
[Stat] Mod: The amount of the stat is affected when the skill is cast

When you are done setting up your new skill, push “Generate” to have the skill code generated for you!

Tips
Transformations:
Animals/Creatures that are a single paperdoll layer are stored in the body.dat file. Transformations into
such creatures results in only displaying the players body which represents this creature. You can
specify which stats are affected from this transformation. Everything from Elemental bonus to stat
modifications are applied! This can be used by NPCs and PCs

Summoning NPC:
Only player characters can perform summoning. Enter into the Summon NPC field the NPC Index of
the NPC you wish to have summoned.

Teleport:
Only player characters can teleport. Enter the map, x, and y coordinates and the Teleport Effect
(particles) you wish to display. The Teleport effect is a numeric value which corresponds to the particle
effect you wish to use. You can see which numbers refer to what effect in
Client.TCP.Data_Server_Teleport. You can also add more effects in this section of code.

Adjust Stats
You can have your new skill affect just the stats, and thus create bonuses, curses, etc that impact your
target. This can be used by NPCs and PCs.

The Spell Icon is the icon you would like to have displayed above the caster's head. You can manually
type in your custom icon or select from existing icons in the list. An example value is

Return To Help Topics


DataCode.Server_IconWarCursed

Hard-Coding Skills
The most important part of the spell code is the spell code itself. These are all held in the server's Skills
module. Most of the default vbGORE spells offer support for casting from PC->NPC, NPC->NPC, and
PC->PC. Also, constants are added to the top to easily define certain values. These are not required, but
it is recommended for ease-of-use. Its all about personal style, though.

The code snippets below are only examples.

Checking Conditions:
The first part of the skill sub is checking for valid conditions. This depends on if the caster or target is a
NPC or PC. Casting between two PCs will have the most checks.
Start with making sure the user is even in the state to cast the spell or be casted on, such as if they are
online (or the NPC is alive). For example, from PC->PC:
If UserList(CasterIndex).flags.UserLogged = 0 Then Exit Sub
If UserList(TargetIndex).flags.UserLogged = 0 Then Exit Sub
If UserList(CasterIndex).Counters.SpellExhaustion > 0 Then Exit Sub

The next step is to make sure the user who is casting the skill knows it. If it is a NPC, it is often safe to
assume that if the routine is being called, they are supposed to be casting it, so checks on NPC for this
is not required:
'Check if the caster knows the skill
If UserList(CasterIndex).KnownSkills(SkID.Bless) = 0 Then
Data_Send ToIndex, CasterIndex, cMessage(37).Data
Exit Sub
End If

After this, make sure the caster (NPC or PC) has enough mana, stamina or health to use the skill if any
is needed. For example:
'Check for enough mana to cast
If UserList(CasterIndex).Stats.BaseStat(SID.MinMAN) <
Int(UserList(CasterIndex).Stats.ModStat(SID.Mag) * Bless_Cost) Then
Data_Send ToIndex, CasterIndex, cMessage(38).Data
Exit Sub
End If

For users, it is often important to, just in case, put in a distance check before the skill is used if it is
target-based:
'Check for a valid target distance
If Server_CheckTargetedDistance(CasterIndex) = 0 Then Exit Sub

Return To Help Topics


Using The Skill
We now know the user passes all conditions to use the skill. From here on, we assume the skill will be
used successfully, so reduce the user's stats if needed (ie mana):
'Reduce the mana
UserList(CasterIndex).Stats.BaseStat(SID.MinMAN) =
UserList(CasterIndex).Stats.BaseStat(SID.MinMAN) -
Int(UserList(CasterIndex).Stats.ModStat(SID.Mag) * Bless_Cost)

For ailments or buff spells, like a Curse or Blessing, you will often want to make sure that the user
doesn't already have the skill applied on them with a stronger power. The reason for this is you don't
want someone to be able to have a weaker buff casted on them by their enemy to cancel theirs out. A
good idea is to allow the skill to be casted on them either way if the one casted on them is about to run
out - this will allow users to avoid that "unbuffed time" between when the old buff runs out, and the
new one is casted. The below example doesn't do this, though:
'Cast on the target
If UserList(TargetIndex).Counters.BlessCounter > 0 Then
If UserList(TargetIndex).Skills.Bless >
UserList(CasterIndex).Stats.ModStat(SID.Mag) Then

Next is to deal with the icons displayed above the caster and target, if any. The most common on is the
spell exhaustion (time that must be waited between casting skills). The below is an example that will
display the bless icon:
'Display the bless icon (only if it isn't already displayed)
If UserList(TargetIndex).Skills.Bless = 0 Then
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconBlessed
ConBuf.Put_Byte 1
ConBuf.Put_Integer UserList(TargetIndex).Char.CharIndex
Data_Send ToMap, CasterIndex, ConBuf.Get_Buffer,
UserList(CasterIndex).Pos.Map, PP_StatusIcons
End If

And spell exhaustion (icon plus adding the spell exhaustion time):
'Add the spell exhaustion and display it
UserList(CasterIndex).Counters.SpellExhaustion = timeGetTime Bless_Exhaust
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconSpellExhaustion
ConBuf.Put_Byte 1
ConBuf.Put_Integer UserList(CasterIndex).Char.CharIndex
Data_Send ToMap, CasterIndex, ConBuf.Get_Buffer, UserList(CasterIndex).Pos.Map,
PP_StatusIcons

Keep in mind that times are calculated as CurrentTime Length (in milliseconds), not just length. This
helps reduce CPU load for timer-based calculations, along with much more accuracy.
Theres a few more display tasks left. The below is an example of how to tell the caster and target that
bless was casted:
'Send the message to the caster
If TargetIndex <> CasterIndex Then

Return To Help Topics


ConBuf.PreAllocate 3 Len(UserList(TargetIndex).Name)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 40
ConBuf.Put_String UserList(TargetIndex).Name
Data_Send ToIndex, CasterIndex, ConBuf.Get_Buffer

'Face the caster to the target


UserList(CasterIndex).Char.Heading =
Server_FindDirection(UserList(CasterIndex).Pos, UserList(TargetIndex).Pos)
UserList(CasterIndex).Char.HeadHeading = UserList(CasterIndex).Char.Heading
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.User_Rotate
ConBuf.Put_Integer UserList(CasterIndex).Char.CharIndex
ConBuf.Put_Byte UserList(CasterIndex).Char.Heading
Data_Send ToMap, CasterIndex, ConBuf.Get_Buffer,
UserList(CasterIndex).Pos.Map

End If

'Send the message to the target


ConBuf.PreAllocate 5 Len(UserList(CasterIndex).Name)
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 41
ConBuf.Put_String UserList(CasterIndex).Name
ConBuf.Put_Integer UserList(CasterIndex).Skills.Bless
Data_Send ToIndex, TargetIndex, ConBuf.Get_Buffer

Now, for the display effects. This has to be handled more on the client which we will get to later. If you
want to display a spell effect, you will have to pass the skill ID, then specific parameters for that skill
ID. Often, this is just the character index of the target and caster:
'Display the effect
ConBuf.PreAllocate 6
ConBuf.Put_Byte DataCode.User_CastSkill
ConBuf.Put_Byte SkID.Bless
ConBuf.Put_Integer UserList(CasterIndex).Char.CharIndex
ConBuf.Put_Integer UserList(TargetIndex).Char.CharIndex
Data_Send ToMap, CasterIndex, ConBuf.Get_Buffer, UserList(CasterIndex).Pos.Map,
PP_DisplaySpell

Finally, the very last thing is the sound. The sound requires just sending the sound number (such as 6
for 6.wav) along with the tile position:
'Play sound effect
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_PlaySound3D
ConBuf.Put_Byte Bless_Sfx
ConBuf.Put_Byte UserList(CasterIndex).Pos.X
ConBuf.Put_Byte UserList(CasterIndex).Pos.Y
Data_Send ToPCArea, CasterIndex, ConBuf.Get_Buffer, , PP_Sound

Return To Help Topics


Adding The Skill ID
The skill ID (SkillID) is what is used to let the server and client tell each other what skill is being used
without passing the name. The skill ID is held in the DataIDs module, which is part of the Common
Code, which means the client and server use the same module. If you change the code in the server, for
example, it will be shown in the client when you load it up.
Scroll down to:
Public Type SkillID
Bless As Byte
Protection As Byte
Strengthen As Byte
Warcry As Byte
Heal As Byte
IronSkin As Byte
SpikeField As Byte
SummonBandit As Byte
End Type
Public SkID As SkillID 'Skill IDs
Public Const NumSkills As Byte = 8

Anywhere in the SkillID UDT, add the name of your skill, such as:
MySkill As Byte

Make sure you update the NumSkills constant with the number of skills you have. In most cases, this
will be the same number as there are variables in the SkillID UDT.
Public Const NumSkills As Byte = 9 'Change to highest skill ID

Now apply the value to the new skill by finding:


With SkID
.Bless = 1
.Heal = 2
.IronSkin = 3
.Protection = 4
.Strengthen = 5
.Warcry = 6
.SpikeField = 7
.SummonBandit = 8
End With

And adding in the next free number for your skill, such as:
.MySkill = 9

SkillID To …
While the server only needs to know the SkillID number and what skill subs it relates to, the client
needs to be able to convert the skill ID into the skill name and grh to display the skill information on
the client. These subs are Engine_SkillIDtoGRHID and Engine_SkillIDtoSkillName. The usage for
them are very self explanatory, you just have to enter the Grh number and skill name.

Return To Help Topics


After following these steps, if your user knows the skill, they should be able to see it in their skill
selection list, which can be brought up by Shift LeftClick on a quick bar slot.

Status Effects and Timers


A huge part about spells is adding ailments and timers. For example, if you want to have a Curse spell
that lowers all of the user's stats and lasts for 5 minutes, will need a timer variable to say it lasts for 5
minutes, and a variable to say to tell the server the spell is on the user, and how powerful the spell is.
On the server, look for:
Type UserCounters

You will see a lot of skill counters in here already. As stated before, the value stored in this counter is
not how long the skill lasts, but at what time the skill will run out, which is found by timeGetTime
Length, and is represented in milliseconds. Keep all counters as a Long.
Next, for adding the information of the skill to the user, search for:
Type Skills

This holds the power of the skill. How you use and calculate this value is up to you. Some skills, like
Iron Skill, is just either on or off, while the others are held by value, where a higher value = higher
power.
Next, you want to make sure you are checking to see if the counter runs out. Plenty of examples of this
can be found if you look for the code:
'*** Update the counters ***

For example, here is bless:


If UserList(UserIndex).Counters.BlessCounter > 0 Then
If UserList(UserIndex).Counters.BlessCounter <
timeGetTime Then
UserList(UserIndex).Skills.Bless = 0
ConBuf.PreAllocate 4
ConBuf.Put_Byte DataCode.Server_IconBlessed
ConBuf.Put_Byte 0
ConBuf.Put_Integer
UserList(UserIndex).Char.CharIndex
Data_Send ToMap, UserIndex, ConBuf.Get_Buffer,
UserList(UserIndex).Pos.Map, PP_StatusIcons
User_UpdateModStats UserIndex
End If
End If

The basic concept of this is if the spell ran out, set the skill value to 0 (turn off the ailment), turn off the
icon and update their mod stats.
The final step is to make use of the ailment. This is done in User_UpdateModStats. For example:
'Protection
If UserList(UserIndex).Skills.Protect > 0 Then
Log "User_UpdateModStats: Updating effects of skill/spell Protection",

Return To Help Topics


CodeTracker '//\\LOGLINE//\\
.ModStat(SID.DEF) = .ModStat(SID.DEF)
UserList(UserIndex).Skills.Protect
End If

Make sure you use ModStat and BaseStat appropriately.

Color Selector

This is a useful tool that you most likely will be using when you want to figure out the ARGB color of
something.
For example, if you want your menus to appear translucent, you could input
• Alpha: 100
• Red: 255
• Green: 255
• Blue: 255
Alpha, Red, Green, and Blue range from 0 (none) to 255 (fullest). Changing these values for Red,
Green, and Blue to different combinations will yield different colors. For example. 255 for Red and
Green and 0 for Blue will create Yellow. Changing the value of Alpha will make something more
transparent.

File Processor
Open ToolFileProcessor.exe. In this tutorial I will use RC4 Algorithim so select the Algorithim RC4,
put the key and the altered extension. The Unaltered Extension and Sub-Folder will be the default
("PNG" and "Grh\").

Return To Help Topics


Open GameClient.vbp
In TileEngine>Sub Engine_Init_Texture, declare
Dim TempFile as String

Replace this:
'Get the path
FilePath = GrhPath & TextureNum & ".png"

'Check if the texture exists


If Engine_FileExist(FilePath, vbNormal) = False Then
MsgBox "Error! Could not find the following texture file:" & vbNewLine &
FilePath, vbOKOnly
IsUnloading = 1

Return To Help Topics


Exit Sub
End If

To this:
'Get the path
TempFile = GrhPath & TextureNum & ".enc" '<<<<PUT THE ALTERED EXTENSION
FilePath = GrhPath & TextureNum & ".png"

'Check if the texture exists


If Engine_FileExist(TempFile, vbNormal) = False Then
MsgBox "Error! Could not find the following texture file:" & vbNewLine &
TempFile, vbOKOnly
IsUnloading = 1
Exit Sub
End If

'Decrypt the file


Encryption_RC4_DecryptFile TempFile, FilePath, "key" '<<<<PUT THE ENCRYPT KEY

After End Sub Add


Kill FilePath

Example Image:

Return To Help Topics


Now go to TileEngine>Sub Engine_Init_ParticleEngine then Replace the whole thing with this:
Sub Engine_Init_ParticleEngine(Optional ByVal SkipToTextures As Boolean = False)
'*****************************************************************

Return To Help Topics


'Loads all particles into memory - unlike normal textures, these stay in memory.
This isn't
'done for any reason in particular, they just use so little memory since they are
so small
'More info: http://www.vbgore.com/GameClient.TileEngine.Engine_Init_ParticleEngine
'*****************************************************************
Dim i As Byte
Dim TempPart As String
Dim FilePart As String

If Not SkipToTextures Then

'Set the particles texture


NumEffects = Var_Get(DataPath & "Game.ini", "INIT", "NumEffects")
ReDim Effect(1 To NumEffects)

End If

For i = 1 To UBound(ParticleTexture())
TempPart = GrhPath & "p" & i & ".enc"
FilePart = GrhPath & "p" & i & ".png"

Encryption_RC4_DecryptFile TempPart, FilePart, "key" '<<<<<<PUT YOUR KEY


HERE

If ParticleTexture(i) Is Nothing Then Set ParticleTexture(i) = Nothing


Set ParticleTexture(i) = D3DX.CreateTextureFromFileEx(D3DDevice, FilePart,
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
D3DX_FILTER_POINT, D3DX_FILTER_POINT, &HFF000000, ByVal 0, ByVal 0)
Next i

End Sub

Decrypt Particles Created by DjMaddius


Special Thanks to onez0r

Free Number Finder


ToolFreeNumber.exe

Return To Help Topics


This tool is used to find the next unused Grh (grh.raw) and texture (*.png) names. It automatically
finds for you the 15 smallest unused graphic file number and unused GRH value for your convenience.
Since everything has to have a unique name, knowing the next available name is quite useful.

Log Remover
ToolLogRemover.exe

A tool that removes the current log files of the game. It is good to occasionally clean up the logs when
they get too big.

Grh Categorizer
ToolGrhCategorizer.exe

This tool allows to sort all your GRH's graphics into different categorises for easier use in the
EditorMap.

Return To Help Topics


Grh Dat Maker
ToolGrhDatMaker.exe

Turns your Grh1.raw files into Grh.dat files, and calculates the values for your Grh.ini file. Every time
you add or make changes to a Grh, you must run this tool to have it show up in the game.

Grh Raw Assistant


ToolGrhRawAssistant.exe

Return To Help Topics


This tool can help you create, edit, and remove Grhs. All that is involved is opening up the texture file
(*.png) and then inputing the width, height, and other properties of the Grh.

Before you do anything, you have to open a texture (*.png) file! Click the “...” button do do this. Once
you open a texture file, the widthe, height, and other information for it will be displayed under “Texture
Information”

This tool has a built in feature to display a grid. You can set the width and height, total rows and
columns, and the starting coordinate for this grid. The grid is simply used to create a series of “Grid-
Created Grhs” in the bottom left corner of the editor. This is a shortcut way of creating Grhs. Should
you use this method, just click the “Append” button at the top right corner of the editor to add all the
“Grid-Created Grhs.” If there is a Grh in the list you don't want, you can select it and push the Delete
key to remove it. If you make adjustments to the grid (such as width, start coordinate, etc), push
Refresh to update the grid and “Grid-Created Grhs.”

Adding Grh

Click “Add GRH” button on the far left of the editor to add a new Grh.
Grh: The Grh number for your new Grh. Use the ToolFreeNumber.exe for help finding next free
number (Or click Next Free Grh).
File: This is the texture file number, inserted automatically for you based on the currently open *.png
Width/Height: The dimensions of your Grh
X,Y: The coordinate of your Grh in the texture file.
Category: You can optionally input the category number for your Grh. If unsure, you can later do this
with the ToolGrhCategorizer.exe

When done, push save.

Return To Help Topics


Editing and Deleting Grh

On the far left side, under Existing Grhs, select a Grh from the list. When you do, the Grh will be
highlighted with a yellow border in the displayed texture. For Example:

Next, click the “Edit GRH” button to edit (Or Remove to delete). In the form that opens, the following
fields will be automatically filled in with the properties of the selected Grh.
Grh: The Grh number for your Grh.
File: This is the texture file
Width/Height: The dimensions of your Grh
X,Y: The coordinate of your Grh in the texture file.
Category: The category for you texture, used for easier finding of your Grh in the map editor. If
unsure, you can later do this with the ToolGrhCategorizer.exe

Change the values to your liking, and then click save. If you are removing the Grh, click the Remove
button instead. Note, If the Grh being edited is animated, the form in the following section would
actually show.

Return To Help Topics


Animated Grh

Click on the “Add Animated” to add a Grh that is animated. In the form that opens, the following
fields will show:
File: The texture file (inserted for you based on the open texture file)
Grh: The number for the new Grh
Frames: The frames in your animated Grh
• <Frames( >1)>: The total frames in your animation (must be greater than 1)
• -#-#-#-#...: The list of Grhs for each frame of the animation. For example, if you had 3 frames
in your animation, you would put something like this: 245-246-247
• <Speed>: The frame rate for the animation. The higher, the faster.

Example:
2-365-388-8-(128)

There's one button not mentioned yet, and that is “Open GrhRaw.txt” which will open the GrhRaw.txt
file so you can manually edit the grh list file directly, rather than through this editor. That is something
you should only do if you know what you are doing.

IMPORTANT!
Don't forget, run the ToolGrhDatMaker.exe after you add/edit/remove Grhs!

Return To Help Topics


General Information

Control Panel

This tool is provided for mere convenience. From this tool you can open up either the source code or
executable for all the editors, game client, server, update client/server, etc.

Adding NPC AIs


vbGORE comes with several options for NPC behavior built-in, such as simple random movement,
running towards and attacking a player, or running away from a player. For any serious, large-scale
MMORPG, however, you'll eventually want to write your own.
Every NPC AI code is located in the server's NPC_AI routine - GameServer.NPCs.NPC_AI. This is
called during the server's game loop, when the NPC has passed all the checks for updating - it's alive,
it's on a map with users, its action timer has expired (it's time for it to act again), etc.

Return To Help Topics


Below is an example of adding an AI for a summoned NPC with a ranged attack. This is the same
tutorial found on vbGORE wiki
For the sake of this tutorial, we're going to add AI for a summoned NPC with a ranged attack - in this
case he can be a Summoned Ninja. Find the NPC_AI sub, and find a blank spot before the End
Select statement. We're going to add the case for our new AI there, so go ahead and add a comment
header describing your AI, and the Case number (for this, we want 8). As so:
'*** Summoned Ranged Attacker ***
Case 8

End Select

End Sub

All the code under Case 8 will run whenever an NPC with its AI set to 8 acts. So how do we want this
NPC to behave? First, as with the summoned melee attacker (Case 7), we want to make sure that it's
only run by a summoned NPC with an owner:

'*** Summoned Ranged Attacker ***


Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

End Select

End Sub

It will reset the action timer and abort the sub if the NPC doesn't have an owner. If the rest of your code
is well-designed, this sub should never be called by a non-summoned NPC anyway, but it's always
better to be safe than sorry.
Next, we want our NPC to look around for any other NPCs it should be attacking (for now, our NPC
will only attack other NPCs, as PvP is a little harder to do).
'*** Summoned Ranged Attacker ***
Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

'Look for a near-by NPC


i = NPC_AI_ClosestNPC(NPCIndex, NPCList(NPCIndex).AttackRange \ 2,
NPCList(NPCIndex).AttackRange \ 2, NPCList(NPCIndex).OwnerIndex, 1, 1)

Return To Help Topics


End Select

End Sub

If you're not entirely sure what the NPC_AI_ClosestNPC sub does, it's easy enough to check (it's in
the same module). What this sub does is returns the index of the NPC closest to our NPC, inside the
range we specify. It also has options for if the NPC has to be hostile, if the NPC has to be attackable,
and if the NPC can't be owned by a certain player. If it finds no NPCs, it will return 0, so let's check for
that:

'*** Summoned Ranged Attacker ***


Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

'Look for a near-by NPC


i = NPC_AI_ClosestNPC(NPCIndex, NPCList(NPCIndex).AttackRange \ 2,
NPCList(NPCIndex).AttackRange \ 2, NPCList(NPCIndex).OwnerIndex, 1, 1)

'Check to see if we could find something


If i = 0 Then

End Select

End Sub

So what do we want the NPC to do if there isn't anything to attack? We'll have it follow the user
around, because it's a summon. In this case, we can just copy+paste some code from Case 7 again:
'*** Summoned Ranged Attacker ***
Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

'Look for a near-by NPC


i = NPC_AI_ClosestNPC(NPCIndex, NPCList(NPCIndex).AttackRange \ 2,
NPCList(NPCIndex).AttackRange \ 2, NPCList(NPCIndex).OwnerIndex, 1, 1)

'Check to see if we could find something


If i = 0 Then
'There is nothing around to attack, so we want to tell it to move
towards the user (we're following a bit behind, don't want to get too close to the
action)
If Abs(CInt(NPCList(NPCIndex).Pos.X) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.X)) < 4 Then

Return To Help Topics


If Abs(CInt(NPCList(NPCIndex).Pos.Y) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.Y)) < 4 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 500
Exit Sub
End If
End If
End Select

End Sub

That last bit of code might not make too much sense, because it's probably backwards from what you're
thinking. What these If statements are doing is checking if the NPC is already close enough to the
user, instead of checking if the NPC needs to move closer. So what we have so far, in pseudocode, is
basically:
If there is no valid target in range, Then:
If we're close enough to the user that we don't have to move, Then:
We don't have to do anything, so abort the routine.

However, if we aren't close enough to the user, we have to move towards him. Since it will
automatically exit the sub if the NPC is close enough, we can simply add the code without an Else
statement.
'*** Summoned Ranged Attacker ***
Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

'Look for a near-by NPC


i = NPC_AI_ClosestNPC(NPCIndex, NPCList(NPCIndex).AttackRange \ 2,
NPCList(NPCIndex).AttackRange \ 2, NPCList(NPCIndex).OwnerIndex, 1, 1)

'Check to see if we could find something


If i = 0 Then
'There is nothing around to attack, so we want to tell it to move
towards the user (we're following a bit behind, don't want to get too close to the
action)
If Abs(CInt(NPCList(NPCIndex).Pos.X) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.X)) < 4 Then
If Abs(CInt(NPCList(NPCIndex).Pos.Y) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.Y)) < 4 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 500
Exit Sub
End If
End If

'So let's set the direction toward the player, and try to move
tHeading = Server_FindDirection(NPCList(NPCIndex).Pos,
UserList(NPCList(NPCIndex).OwnerIndex).Pos)

If NPC_MoveChar(NPCIndex, tHeading) = 0 Then


'Couldn't move so look for alternate paths

Return To Help Topics


End Select

End Sub

Now what we've done is set a variable called tHeading to the direction the user is in, using the
Server_FindDirection function. We then try to move using the NPC_MoveChar function.
NPC_MoveChar tries to move, and if it is successful (the NPC can move) it returns 1. Needless to say,
if it isn't, it returns 0. So let's assume we can't move in a direct line to the user. We're going to try and
move diagonally or to the side now (for the sake of saving space, I've cut off the top part of the code):
If Abs(CInt(NPCList(NPCIndex).Pos.X) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.X)) < 4 Then
If Abs(CInt(NPCList(NPCIndex).Pos.Y) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.Y)) < 4 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 500
Exit Sub
End If
End If

'So let's set the direction toward the player, and try to move
tHeading = Server_FindDirection(NPCList(NPCIndex).Pos,
UserList(NPCList(NPCIndex).OwnerIndex).Pos)

If NPC_MoveChar(NPCIndex, tHeading) = 0 Then


'Couldn't move so look for alternate paths
Select Case tHeading
Case NORTH
t1 = NORTHEAST
t2 = NORTHWEST
t3 = EAST
t4 = WEST
Case EAST
t1 = NORTHEAST
t2 = SOUTHEAST
t3 = NORTH
t4 = SOUTH
Case SOUTH
t1 = SOUTHWEST
t2 = SOUTHEAST
t3 = WEST
t4 = EAST
Case WEST
t1 = SOUTHWEST
t2 = NORTHWEST
t3 = SOUTH
t4 = NORTH
Case NORTHEAST
t1 = NORTH
t2 = EAST
t3 = NORTHWEST
t4 = SOUTHEAST
Case SOUTHEAST
t1 = EAST
t2 = SOUTH
t3 = SOUTHWEST

Return To Help Topics


t4 = NORTHEAST
Case SOUTHWEST
t1 = SOUTH
t2 = WEST
t3 = SOUTHEAST
t4 = NORTHWEST
Case NORTHWEST
t1 = WEST
t2 = NORTH
t3 = NORTHEAST
t4 = SOUTHWEST
End Select
End Select

End Sub

That's pretty big, but simple. t1, t2, t3, and t4 represent the alternate directions we can move in. If
you trace through that code a bit, you shouldn't have much trouble gathering what it does.
Now we're going to actually try and move in those 4 directions.
Case SOUTHWEST
t1 = SOUTH
t2 = WEST
t3 = SOUTHEAST
t4 = NORTHWEST
Case NORTHWEST
t1 = WEST
t2 = NORTH
t3 = NORTHEAST
t4 = SOUTHWEST
End Select
'Try the alternate movements
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move, so just wait
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + 1000
End If
End If
End If
End If
End Select

End Sub

You can probably figure out what this does by now. It tries moving in each alternate direction, and if it
still can't move, it will simply wait. We could implement some sort of advanced pathfinding algorithm
to get around obstacles, but let's just say our NPC is dumb :P
Case NORTHWEST
t1 = WEST
t2 = NORTH
t3 = NORTHEAST

Return To Help Topics


t4 = SOUTHWEST
End Select
'Try the alternate movements
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move, so just wait
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + 1000
End If
End If
End If
End If
End If
Exit Sub

Else
'Something was found, so now we get in position and attack!
'Get the position of the NPC
tPos = NPCList(i).Pos
End Select

End Sub

What we've done now is add the trailing End If statement for If NPC_MoveChar(NPCIndex,
tHeading) = 0 Then, and then aborted the sub. If we've gotten this far in the routine, we've either
moved or not and there are no enemies, so we don't need to do anything else. If you're a bit confused,
take a look at this updated pseudocode for our AI so far:

If there is no valid target in range, Then:


If we're close enough to the user that we don't have to move, Then:
We don't have to do anything, so abort the routine.
End If

Try to move directly towards the user. If we can't Then:


Try to move in an alternate path. If we still can't, Then:
We can't do anything else, so set our timer to wait and try again.
End If
End If

We've either moved or not by now, and there's no target, so abort the routine.

Else
We do have a target to attack, so get the target's position.

Now I'm going to post all the code for moving to the correct distance from the NPC. Don't worry, I'll
explain it.
Else
'Something was found, so now we get in position and attack!
'Get the position of the NPC
tPos = NPCList(i).Pos

Return To Help Topics


'Run away and get in position if we're too close
If Server_RectDistance(NPCList(NPCIndex).Pos.X,
NPCList(NPCIndex).Pos.Y, tPos.X, tPos.Y, 3, 3) Then
tHeading = Server_FindDirection(NPCList(NPCIndex).Pos, tPos)
'We're going away from it so pick the opposite direction
Select Case tHeading
Case NORTH: tHeading = SOUTH
Case NORTHEAST: tHeading = SOUTHWEST
Case EAST: tHeading = WEST
Case SOUTHEAST: tHeading = NORTHWEST
Case SOUTH: tHeading = NORTH
Case SOUTHWEST: tHeading = NORTHEAST
Case WEST: tHeading = EAST
Case NORTHWEST: tHeading = SOUTHEAST
End Select

'Now let's attempt to move away


If NPC_MoveChar(NPCIndex, tHeading) = 0 Then
'Can't move there, so try alternate directions
Select Case tHeading
Case NORTH
t1 = NORTHEAST
t2 = NORTHWEST
t3 = EAST
t4 = WEST
Case EAST
t1 = NORTHEAST
t2 = SOUTHEAST
t3 = NORTH
t4 = SOUTH
Case SOUTH
t1 = SOUTHWEST
t2 = SOUTHEAST
t3 = WEST
t4 = EAST
Case WEST
t1 = SOUTHWEST
t2 = NORTHWEST
t3 = SOUTH
t4 = NORTH
Case NORTHEAST
t1 = NORTH
t2 = EAST
t3 = NORTHWEST
t4 = SOUTHEAST
Case SOUTHEAST
t1 = EAST
t2 = SOUTH
t3 = SOUTHWEST
t4 = NORTHEAST
Case SOUTHWEST
t1 = SOUTH
t2 = WEST
t3 = SOUTHEAST
t4 = NORTHWEST
Case NORTHWEST

Return To Help Topics


t1 = WEST
t2 = NORTH
t3 = NORTHEAST
t4 = SOUTHWEST
End Select
'Try the alternate moves
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move (cornered! ack!) so
attack!
NPC_AI_AttackNPC NPCIndex,
NPCList(NPCIndex).OwnerIndex
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + NPCDelayFight
End If
End If
End If
End If
End If
Exit Sub
End If
End Select

End Sub

Lotta code right there. However, if you're keen, you'll have noticed it looks almost like the code we
used before (In fact, much of it IS the code we used before. I'm far too lazy to write it all out again.
Nothing wrong with a little Ctrl+C action). Let's use some more pseudocode to explain what this is
doing. Refer to this little snippet, and then back at the code, and see if you can piece together what the
code is doing:
If there is no valid target in range, Then:
If we're close enough to the user that we don't have to move, Then:
We don't have to do anything, so abort the routine.
End If

Try to move directly towards the user. If we can't Then:


Try to move in an alternate path. If we still can't, Then:
We can't do anything else, so set our timer to wait and try again.
End If
End If

We've either moved or not by now, and there's no target, so abort the routine.

Else
We do have a target to attack, so get the target's position.
If we're closer than 3 tiles to the target, Then:
Set tHeading to the opposite direction of where the target is
Try to move in that direction. If we can't Then:
Try to move in an alternate path. If we still can't, Then:
We can't move, but we have a target, so attack.
End If
End If
We've either moved away or attacked, so abort the routine.

Return To Help Topics


End If

Making sense now? We're almost done, but we need some more code. What happens if we're already 3
tiles from the target? We want to go ahead and attack, so:
'Try the alternate moves
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move (cornered! ack!) so
attack!
NPC_AI_AttackNPC NPCIndex,
NPCList(NPCIndex).OwnerIndex
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + NPCDelayFight
End If
End If
End If
End If
End If
Exit Sub
End If

'We're already in position, so just attack


b = NPC_AI_AttackNPC(NPCIndex, NPCList(NPCIndex).OwnerIndex)
If b Then
'Make sure the attack was successful before applying the delay
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime +
NPCDelayFight
Exit Sub
End If

'Nothing to do, so just wait and try again in a second


NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 1000

End If

End Select

End Sub

By now, you probably have a good idea of what those last few lines are. For reference,
NPC_AI_AttackNPC returns a 1 if the attack is successful and a 0 if it wasn't. The ActionDelay
counter is there to make sure that the NPC attacks on-time - don't want him attacking too fast or too
slow.
Believe it or not, that's the end! Here's the completed pseudocode for AI number 8:
If there is no valid target in range, Then:
If we're close enough to the user that we don't have to move, Then:
We don't have to do anything, so abort the routine.
End If

Try to move directly towards the user. If we can't Then:


Try to move in an alternate path. If we still can't, Then:

Return To Help Topics


We can't do anything else, so set our timer to wait and try again.
End If
End If

We've either moved or not by now, and there's no target, so abort the routine.

Else
We do have a target to attack, so get the target's position.
If we're closer than 3 tiles to the target, Then:
Set tHeading to the opposite direction of where the target is
Try to move in that direction. If we can't Then:
Try to move in an alternate path. If we still can't, Then:
We can't move, but we have a target, so attack.
End If
End If
We've either moved away or attacked, so abort the routine.
End If

We're longer than 3 tiles away and we've gotten this far in the routine, so
attack.
If the attack was successful, Then:
Update the attack timer.
End If

Update the NPC's AI timer to try again in one second.

And here's the completed AI code. Feel free to copy and paste into your own game, although if all you
do is copy+paste it without reading the tutorial you won't learn much.
'*** Summoned Ranged Attacker ***
'Note: only attacks NPCs for now. Fix later kthx.
Case 8

'This routine is for summoned NPCs only!


If NPCList(NPCIndex).OwnerIndex = 0 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 5000
Exit Sub
End If

'Look for a near-by NPC


i = NPC_AI_ClosestNPC(NPCIndex, NPCList(NPCIndex).AttackRange \ 2,
NPCList(NPCIndex).AttackRange \ 2, NPCList(NPCIndex).OwnerIndex, 1, 1)

'Check to see if we could find something


If i = 0 Then
'There is nothing around to attack, so we want to tell it to move
towards the user (we're following a bit behind, don't want to get too close to the
action)
If Abs(CInt(NPCList(NPCIndex).Pos.X) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.X)) < 4 Then
If Abs(CInt(NPCList(NPCIndex).Pos.Y) -
CInt(UserList(NPCList(NPCIndex).OwnerIndex).Pos.Y)) < 4 Then
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 500
Exit Sub
End If
End If
'So let's set the direction toward the player, and try to move

Return To Help Topics


tHeading = Server_FindDirection(NPCList(NPCIndex).Pos,
UserList(NPCList(NPCIndex).OwnerIndex).Pos)

If NPC_MoveChar(NPCIndex, tHeading) = 0 Then


'Couldn't move so look for alternate paths
Select Case tHeading
Case NORTH
t1 = NORTHEAST
t2 = NORTHWEST
t3 = EAST
t4 = WEST
Case EAST
t1 = NORTHEAST
t2 = SOUTHEAST
t3 = NORTH
t4 = SOUTH
Case SOUTH
t1 = SOUTHWEST
t2 = SOUTHEAST
t3 = WEST
t4 = EAST
Case WEST
t1 = SOUTHWEST
t2 = NORTHWEST
t3 = SOUTH
t4 = NORTH
Case NORTHEAST
t1 = NORTH
t2 = EAST
t3 = NORTHWEST
t4 = SOUTHEAST
Case SOUTHEAST
t1 = EAST
t2 = SOUTH
t3 = SOUTHWEST
t4 = NORTHEAST
Case SOUTHWEST
t1 = SOUTH
t2 = WEST
t3 = SOUTHEAST
t4 = NORTHWEST
Case NORTHWEST
t1 = WEST
t2 = NORTH
t3 = NORTHEAST
t4 = SOUTHWEST
End Select
'Try the alternate movements
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move, so just wait
'(we could implement some sort of advanced
pathfinding, but let's just say our NPCs failed their IQ tests :P )
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + 1000

Return To Help Topics


End If
End If
End If
End If
End If
Exit Sub

Else
'Something was found, so now we get in position and attack!
'Get the position of the NPC
tPos = NPCList(i).Pos

'Run away and get in position if we're too close


If Server_RectDistance(NPCList(NPCIndex).Pos.X,
NPCList(NPCIndex).Pos.Y, tPos.X, tPos.Y, 3, 3) Then
tHeading = Server_FindDirection(NPCList(NPCIndex).Pos, tPos)
'We're going away from it so pick the opposite direction
Select Case tHeading
Case NORTH: tHeading = SOUTH
Case NORTHEAST: tHeading = SOUTHWEST
Case EAST: tHeading = WEST
Case SOUTHEAST: tHeading = NORTHWEST
Case SOUTH: tHeading = NORTH
Case SOUTHWEST: tHeading = NORTHEAST
Case WEST: tHeading = EAST
Case NORTHWEST: tHeading = SOUTHEAST
End Select

'Now let's attempt to move away


If NPC_MoveChar(NPCIndex, tHeading) = 0 Then
'Can't move there, so try alternate directions
Select Case tHeading
Case NORTH
t1 = NORTHEAST
t2 = NORTHWEST
t3 = EAST
t4 = WEST
Case EAST
t1 = NORTHEAST
t2 = SOUTHEAST
t3 = NORTH
t4 = SOUTH
Case SOUTH
t1 = SOUTHWEST
t2 = SOUTHEAST
t3 = WEST
t4 = EAST
Case WEST
t1 = SOUTHWEST
t2 = NORTHWEST
t3 = SOUTH
t4 = NORTH
Case NORTHEAST
t1 = NORTH
t2 = EAST
t3 = NORTHWEST
t4 = SOUTHEAST

Return To Help Topics


Case SOUTHEAST
t1 = EAST
t2 = SOUTH
t3 = SOUTHWEST
t4 = NORTHEAST
Case SOUTHWEST
t1 = SOUTH
t2 = WEST
t3 = SOUTHEAST
t4 = NORTHWEST
Case NORTHWEST
t1 = WEST
t2 = NORTH
t3 = NORTHEAST
t4 = SOUTHWEST
End Select
'Try the alternate moves
If NPC_MoveChar(NPCIndex, t1) = 0 Then
If NPC_MoveChar(NPCIndex, t2) = 0 Then
If NPC_MoveChar(NPCIndex, t3) = 0 Then
If NPC_MoveChar(NPCIndex, t4) = 0 Then
'We still can't move (cornered! ack!) so
attack!
NPC_AI_AttackNPC NPCIndex,
NPCList(NPCIndex).OwnerIndex
NPCList(NPCIndex).Counters.ActionDelay =
timeGetTime + NPCDelayFight
End If
End If
End If
End If
End If
Exit Sub
End If

'We're already in position, so just attack


b = NPC_AI_AttackNPC(NPCIndex, NPCList(NPCIndex).OwnerIndex)
If b Then
'Make sure the attack was successful before applying the delay
NPCList(NPCIndex).Counters.ActionDelay = timeGetTime +
NPCDelayFight
Exit Sub
End If

'Nothing to do, so just wait and try again in a second


NPCList(NPCIndex).Counters.ActionDelay = timeGetTime + 1000

End If

Return To Help Topics


Making an NPC Fight Back
This is another example found on the vbGORE wiki

VBGore comes with several NPC AIs already installed. AI number 2 makes the NPC walk around in a
random pattern. If the NPC is hostile then it will attack players, but if it is not hostile it will not fight
players, even when it has been attacked.
In this tutorial I'll show you how to modify AI number 2 so that NPCs defend themselves when
attacked.

Declaring a New Variable


In the Delclares module search for NPCList() As NPC. Just above it should be all of the variables for
the NPC. Place the following code just before where it says 'THESE ARRAYS MUST STAY DOWN
HERE AT THE BOTTOM OF THE UDT!:
BaseStat(1 To NumStats) As Long 'Declares the NPC's stats
ModStat(FirstModStat To NumStats) As Long 'Declares the NPC's stats

'Begin new code:


Attacked As Byte 'If the NPC was attacked
'End new code

'THESE ARRAYS MUST STAY DOWN HERE AT THE BOTTOM OF THE UDT!
VendItems() As Obj 'Information on the item the NPC is vending

Detect The Attack


In the NPCs module, in the NPC_AI Sub, add this line to Case 2:
'*** Random movement ***
Case 2

'Attack
If NPCList(NPCIndex).Hostile Then b = NPC_AI_Attack(NPCIndex)

'Begin new code


If NPCList(NPCIndex).Attacked Then b = NPC_AI_Attack(NPCIndex)
'End new code

Tell The NPC To Fight Back


In Function User_AttackNPC in the Users module, add this line:
'Calculate hit
Hit = Server_RandomNumber(UserList(UserIndex).Stats.ModStat(SID.MinHIT),
UserList(UserIndex).Stats.ModStat(SID.MaxHIT))
Hit = Hit - (NPCList(NPCIndex).ModStat(SID.DEF) \ 2)
If Hit < 1 Then Hit = 1
Log "User_AttackNPC: Hit (damage) value calculated (" & Hit & ")", CodeTracker

Return To Help Topics


'//\\LOGLINE//\\

'Begin new code:


NPCList(NPCIndex).Attacked = 1
'End new code

This will make the NPC fight back when someone hits it. If you also want to make them hostile when
hit by a range weapon add this code to Private Sub User_Attack_Ranged in the Users module:
'Play the sound of no weapon attacking
SfxID = UnequiptedSwingSfx

End If

'Begin new code:


NPCList(TargetIndex).Attacked = 1
'End new code

'Get the new heading


NewHeading = Server_FindDirection(UserList(UserIndex).Pos, TargetPos)
UserList(UserIndex).Char.Heading = NewHeading
UserList(UserIndex).Char.HeadHeading = NewHeading

Clear The Variable When Respawning


You need to add the following code to the Sub NPC_Spawn in the NPCs module or the NPC will
continue attacking the player after it had respawned:
'Set vars
NPCList(NPCIndex).Pos = TempPos
NPCList(NPCIndex).Counters.BlessCounter = 0
NPCList(NPCIndex).Counters.ProtectCounter = 0
NPCList(NPCIndex).Counters.StrengthenCounter = 0
NPCList(NPCIndex).Counters.WarCurseCounter = 0
NPCList(NPCIndex).Flags.NPCAlive = 1
'Begin new code:
NPCList(NPCIndex).Attacked = 0
'End new code

Adding Graphics
Before you design your Grhs, it is recommended that you know how to optimize your textures for the
best performance.

The Rules Of Textures


First off, you must know the rules that you must follow when designing the textures. The reason we say
textures is because vbGORE treats the graphics as textures, not as surfaces such as DirectDraw does.
The difference is that DirectDraw just copies the pixels from one surface to another, while vbGORE
uses Direct3D to actually perform 3D calculations to display texels.
1. Sizes in powers of 2: The texture sizes must be in powers of 2. This is the texture as a whole, not the

Return To Help Topics


individual Grhs in the texture. The individual Grhs can be any size you want them to be. The width and
height of the texture do not have to be the same power of 2 - for example, you can have 2x128, 4x32,
64x64, etc.
2. No larger than 1024x1024 when possible: Most modern graphic cards can support textures over
1024x1024 resolution, but you want to design your game for all people, not just most people. When
possible, try to make your textures 1024x1024 at largest. If you must, you may increase the resolution,
but the next step to 2048 is a huge increase in size, and can end up very costly and may not be
supported by all graphic cards.

The Texture's Content


What you put on each individual texture can be very important. 256 32x32 textures holds the same as
one 512x512 texture, and the RAM usage is equal for the most part, but the individual small textures
will load slower and result in more overhead. But this doesn't mean the one large texture is better,
either, since you are most likely not going to use all those tiles at once, so why keep them all in
memory at once?
The easiest thing to keep in mind is as little black space as possible. Black space does not refer to the
transparent parts of Grhs, but completely unused parts of the texture. For example, if you have a
200x200 pixel image, putting it in a 256x256 texture is going to waste a lot of space. Often, there is
nothing you can do about it unfortunately.
Now back to the first question, what do we do with a bunch of tiles? What you want to do is group
graphics together that are commonly used together. For example, animations should always remain
together in a single texture (or more if it doesn't fit in just one). Another example is if you have
multiple pieces of a house, you want to put it all in one texture since you will most likely be using a
majority of or all of the pieces at once.
It is important to not spend too much time worrying about it, though. Don't go through extensive
lengths just to group together a few more graphics. In the end, it is often not worth going back to fix
bad designs. If you get in the habit of proper designing from the start, though, you can get the most out
of the engine.

The Image Files


Since the engine is actually a 3d engine, you have to treat the graphics as textures. This means that if
you want them to display correctly, you must obey the following rules:
Size powers of 2
Your width and height of the total bitmap has to be by a power of 2. They do not have to be the
same, though. For example, you can have 2x64, 256x128, 512x2, etc. Failure to follow this will
result in slightly distorted images. This only applies to the texture (whole bitmap image), not the
individual images in the texture (grhs). If you look at the demo GUIs, many of them are random
sizes, but theres black (transparent) space stretching out to the nearest power of 2.
Power of 2 means 2^X, not X/2 (divisible by 2). This means the sizes must be 2, 4, 8, 16, 32, 64,
128, 256, 512, 1024, etc.

Return To Help Topics


No larger then 1024
It is recommended that you don't make any graphic files (textures) larger then 1024 pixels in
width or height. The reason for this is that not all graphic cards are able to support textures of the
next size (2048) and beyond. 1024 pixels is the safest way to go. You should never need to use
more than a 1024x1024 texture, but if you do use such a large texture, you may lose support for
some older graphic cards.

Note that many file types are supported, from BMP, PNG, and JPG to weird extensions most of us have
never even heard of. To use other file extensions, just save as the different file extension and either
change the client and map editor to load the different file extension, or manually change the extension
to PNG (for example, .JPG to .PNG). Note that changing the extension does not have any impact on
the image, it just lets you change the format without changing the engine to look for a different format.
Graphic files are placed in the \Grh\ folder. You can name the file any number, as long as the number
doesn't already exist and does not contain any zeros before the number. Simple numbers like 1, 2, 41,
129, 320, all work. However, numbers like, 002, 0041, 010101, will not work. In the root directory, you
will find a program named ToolFreeNumber.exe. This tool will tell you the next available texture
numbers and grh numbers.

Using GrhRaw.txt
There are two things that identify a graphic, the File/Texture Number (such as 10.png or 210.png) and
Grh Number (defines the individual graphics inside a texture). To create the Grh Number, go to the
\Data2\GrhRaw.txt file and open it with Notepad or Wordpad. In here, you will find entries structured
in these two manners:
1) Grh#=<Frames(=1)>-<FileNumber>-<StartX>-<StartY>-<Width>-<Height>-(<Category>)
2) Grh#=<Frames(>1)>-#-#-#-#-#...-<Speed>-(<Category>)

Your Grh# is the ID number of your Grh. You often don't have to remember this unless you are writing
the GrhNumber directly into the code (like for the GUI) because you can browse through the
GrhNumbers in the map editor. Numbers are required to be unique. In other words, you cannot make
two entries for Grh 10. The compiler will warn you if you make duplicate entries.
At the end is the category. This is optional and is often ignored when making entries directly into
GrhRaw.txt. Categories are handled by the program ToolGrhCategorizer.exe. The rest of this guide
will ignore them, and it is recommended that you do the same when making entries into GrhRaw.txt
Method 1 is for single-frame (unanimated) graphics. Frames will always be 1 in this. FileNumber
refers to the .png file your graphic is in (such as for 20.png, you enter 20). StartX and StartY refer to the
starting pixel position where the graphic you want is, the width and height of the graphic you want is
the width and height of the graphic. For DirectDraw and BitBlt users, think of this as the SourceRect
since you are just defining the part of the image you wish to draw.
Method 2 is for multiple-frame graphics. In this case, Frames must be greater then 1. For each frame,
you must specify a GrhNumber. If you have 5 frames, then you will have 5 GrhNumbers specified after
that. At the end, you have your animation speed, which is how fast the frames elapse (higher = faster).
The speed has no real relative value, so you will want to experiment with how fast the different values
of speed are. Decimals are supported in speed. As an example, in the water animation, you have eight

Return To Help Topics


frames:
Grh3500=8-318-319-320-321-322-323-324-325-9

As you can see, there is an 8 at the start for 8 frames, 8 GrhNumbers which define the 8 different
unanimated (single-frame) grhs, then the speed. A separate GrhNumber must be applied to the
animation that is separate from the other GrhNumbers. Grh3500 is now the animated water, while 318
to 325 is the separate frames of the water.
Another example:
Grh999=8-991-992-993-994-995-996-997-998-7

Grh999 is the Grh number you are assigning to the animation. 8 is the number of frames you have. 991,
992, ... 998 are the Grh numbers of the unanimated Grhs, specified by using Method 1. The last number
in the grounp, 7, is the speed at which the graphic animates.
Once you write the new graphic(s) into the GrhRaw.txt file, run GrhDatMaker.exe. This will compile
GrhRaw.txt into Grh.dat and Grh.ini, which contain the Grh information. This is automatically placed
in the \Data\ folder for you.
Make sure whenever you want to use the map editor which is not part of the client (the non-ingame
map editor) that you copy over the Grh folder along with the Grh.dat and Grh.ini to make sure the
graphics are up to date.

If you are uncomfortable editing the GrhRaw.txt, you can use the ToolGrhRawAssistant.exe to aid you.

Adding Signs
Sign text is stored completely client-side - there is absolutely no reference to it on the server. This is
because even just letting the server know what sign is on what tile is a huge consumption of RAM.
How much, exactly? On a 100x100 map, it would take 100x100x2 or 19 KBytes. It doesn't sound like
much, but spread over 1000s of maps, it adds up fast for an insignificant benefit.
There is only two simple steps required in working with signs. The first step is creating the sign text,
which is located in \Data\Signs.dat. Just open the file with Notepad or Wordpad. You will see the
following:
[SIGNS]

//Displays in the format of:


// The sign says, "<message>"
//Where <message> is the text on the sign (defined below).

NumSigns=5
...

It is important to keep in mind how the engine will translate the sign and display it. The ""'s are
automatically added for you. The The sign says, text comes from the Messages file.

Return To Help Topics


NumSigns holds the highest value in the list of signs. The signs do not have to be written in any
particular order, as long as NumSigns holds the highest value used.
Once the sign is defined, it is ready to be applied through the map editor. Keep in mind you can have a
sign applied on any tile anywhere you wish. You can even change the way signs are handled to make
them display descriptions for certain tiles. You are limited to a total of 32,768 different sign texts,
which shouldn't be limit to worry about.

Useful Links
vbGORE Forums: If you need help with a topic that the user guide nor the vbGORE wiki can answer,
then the forums is a great place to find what you are looking for!
vbGOREmania Forums: Like above, if you can't find what you need on the vbGOREmania website,
then try the vbGOREmania forums!
StreamMyGame: StreamMyGame extends your monitor, keyboard, & mouse over a network so you
can see and play a game or application remotely. You may want to recommend this to your players so
they can play your game anywhere there is an Internet connection (even from their phone!)
PortableApps: A portable app is a computer program that you can carry around with you on a portable
device and use on any Windows computer. When your USB flash drive, portable hard drive, iPod or
other portable device is plugged in, you have access to your software and personal data just as you
would on your own PC. And when you unplug the device, none of your personal data is left behind.
Sprites/Music/More: This section of the vbGOREmania forums contains resources, such as music
and graphics, for your games. Below is just a sample of what has been posted!
• Miscellaneous Sounds
• Animation Editor
• Half Kaizer Graphics
• Google Language Tools
• KB Piano
• Sprite Generator
• Easy Music Composer
• Breeze Graphics
• Pixel Art Tutorials
• vbGORE tutorials / custom features (made by the community)
• vbGOREmania tutorials / custom features (all of these features are already in vbGOREmania's
latest version)
• Weebly: A good website hose for those who are not sure how to setup a website

Return To Help Topics


Game Engine

Features
Quest Window This adds a visual quest log window that the player can interact with.

Blood And Gore!


With permission from Spodi, the blood splatter system of Plagued Dead was added to provide great eye
candy when a player or monster is defeated in battle! Yes, this can be a bit much to look at when you
are on a crowded battlefield, so this feature can be disabled from the Game Configuration tool.
In addition to blood, wounds appear on players when their health is low. Now you can see your victims
hurt and bleed! Wait, that sounds a bit sadistic!

Guilds / Squads
There are guilds (AKA Factions) and squads (AKA Partys) in vbGOREmania. Players can start guilds
and assign ranks to guild members. Players with houses can also choose to lock their house to everyone
but guild members to setup a guild base/meeting place.

Equip Menu
Below the inventory is a small display of what the player has equiped. It is a useful feature for when
the player wants to reference what exactly he/she is wearing!

Status Window
A useful little window that displays the player's location (Map, x, y), Health, Mana, Stamina,
Experience, and Portrait.

Player Housing
You can set maps to be "ownable property." This means that a player can "purchase" this area from a
designated NPC (Servant). Once purchased, the player can later teleport back to this house at any time.
They may also "rest" in this map for instant healing (like at an Inn). They may also give items to the
Servant NPC to sell to players who visit their property. Items they put up for sale are sold at the item's
value + Premium (set by the player to be 5%, 10%, 15% of item value). So yes, the player can basically
have their own store! Players can also "lock" this property so that only friends, only guild members, or
only themselves can have access.
Since some players may eventually stop playing the game, the housing market can get a little out of
hand as the owners no longer play and thus never sell back their houses. That is why there is a time
limit (3 months by default) where if the owner does not visit their home and talk to the Servant, then

Return To Help Topics


the house is considered abandoned and put back up on the market to be bought. When a house is sold,
all items the player had up for sale will be returned to them.
You can be creative with this and have such property be more than houses. You can do caves, castles,
and more! It doesn't even have to be a building. Go wild!
That's not all! What house is complete without furniture? Now players can put furniture in their
houses, castles, or whatever they live in! Stylize your home!

PVP Zones
Maps can be designated in the Map Editor as Player Vs Player areas, meaning that players can fight
each other. In game play, these areas have a skull in the upper right-hand corner to alert the player they
are in such an area.

Reflective Tiles
For extra cool eye candy, you can make certain tiles reflective. This can be done in the Map Editor.
When a player steps on such a tile, their reflection shows up on the tile beneath them.

Class/Level Requirements for Maps


You an set maps to have a class or combat level requirement. Useful for such places such as a "Master
Wizard Guild."

Online User List


On the server itself, you can check to see what players are logged in!

Name and Health Display


When you mouse over a player or NPC, Their name will display above their heads (with any status
icons, i.e. curse, and their combat level) and their health and mana bars will show below their avatar.
The color of their name will also change from green to red based on health.

Mounts And Shields


Mounts (such as horses) and Shields are now available! Saddle up! Note that you can set a level and
class requirement on mounts just like any item. It shows up in the inventory for the player to click on
when they want to riding into that sunset. You can also have the mount provide bonuses, just like any
weapon or item. So, go crazy and fun with this!

Defense
Defense has been added as a stat. A must if you are going to protect yourself!

Return To Help Topics


Custom Appearance Editor
Players can choose to change their hair, head, and body (base body for when they have no gear on)
during game play. We all like to change our look now and then :)

Job Skills
Players can now pursue blacksmithing, alchemy, and Crafting. Blacksmiths can make weapons and
armor, Craftsmen can make furniture, bows, etc, and Alchemist can make potions! All of these are
useful trades for making money and equipment needed for a players passage into greatness!

Windows Lock/Close
Players can lock windows/menus in place to avoid moving them by accident, and they can close them
with the click of a mouse.

Chat Room Updates


Many of the chat commands you can type in the chatroom now have a shortcut key so you don't have
to remember or type anything! There are also chat channels so that you can tune into chats that pertain
to what you want to talk about! Everything from general chat, guild chat, trading, and more are
available! The chat commands can also be hidden.

Elemental Bonuses
Let's face it, in the real world, elements affect each other differently. So, why not have them in your
game so that players can creatue their own strategy as to how to beat that fire breathing dragon or that
ice giant? Knowing the right weapon to bring can make a big difference! Grab your fire shield!

Quickbar Quick Cast


Now you can click on a spell in the quickbar and cast it! Also, you can right click a spell for more
information about it! Same goes for items that are equipped to the quickbar!

Level Up Particle Effect


Tell the truth. Seeing that swirl of energy when you level up makes you happy. Well, it's in the game
engine too! :)

Main Menu
There is now a main menu from which the player can access commonly accessed windows. Forget (or
simply not read the manual)? Well, just click on the Main Menu for easy access!

Return To Help Topics


Updated Character Creation
Players can customize their appearance and their description when creating their characters. Also,
players can have more than one character per account!

GM Tag
In the game chatroom, (GM) appears next to GM's names.

Friend/Ignore List
You can now keep track of your friends/enemies in your own buddy list!

Server Alerts
You can send a global message from the server to all players.

Left Mouse Click Movement


Players can navigate the map by clicking where they want to go.

Control Panel
There is a control panel from which the developers of the game can access any editor, the client/server,
and more.

Chat Channels
The chatroom is broken down into Global, Map, Guild, Market, War, and Help.
• Global: Talk to the world
• Map: Talk to everyone on the same map
• Guild: Talk to other guild members
• Market: Chat with other people who are wanting to trade
• War: Chat with people wanting to dual or coordinate a guild war
• Help: Get help from other players

Editors
• Map Editor: Edit the maps/boards of the game
• Particle Editor: Edit/Create Particle effects
• House Editor: Setup player housing

Return To Help Topics


• Job Editor: Setup Blacksmithing, Alchemy, and Crafting skills.
• NPC Editor: Edit NPCs
• NPC Chat Editor: Edit the NPC chat windows
• Object Editor: Create/Edit the items of the game
• Quest Editor: Create/Edit quests
• Skill Editor: Create Skills/spells
• Color Selector: Get the RGB, ARGB, and Long values for a color
• File Processor: Encrypt Files
• Free Number Finder: Find the next 15 free *.png and grh indices.
• Log Remover: Remove server logs
• Grh Categorizer: Categorize your Grh for easier finding in the Map Editor
• Grh Dat Maker: Turns your Grh1.raw files into Grh.dat files, and calculates the values for your
Grh.ini file.
• Grh Raw Assistant: This tool can help you create, edit, and remove Grhs.

Custom Spawn Point


Players can set their own spawn point. The developer can choose which maps this can be done on
though.

Walk-Through Characters
Characters (players and NPCs) can now walk through each other.

Weather Rotates
The weather rotates periodically to one of three specified weather types specified in the map editor. In
the server, change the variable UpdateRate_Weather to change how fast weather changes.

Rearrange Stats
Players can decrease a stat and move their stat point to another one.

Overhead Tiles Translucent


When a player walks beneath a set of tiles, they become translucent so the player can see what is
around them. You can modify the radius of tiles that disappear by going to the Engine_Render_Screen
function in the client. Search for 'Check if Player is standing beneath tile.

Return To Help Topics


Installing vbGORE(mania)
Using vbGORE or vbGOREmania for the first time can be a bit overwhelming, so here is a guide on
how to get things running from start to finish.

Downloading
First get a copy of the latest version of vbGORE or vbGOREmania.

Extracting
Once your download is done, it is time to extract the files. Go to the folder which you downloaded the
compressed version of vbGORE and right-click the file. Depending on what kind of unzipping software
you have, you will see different things. The typical thing to look for is "Extract" - click Extract To
Folder, Extract To..., Extract To <filename> or something similar. This will extract the contents of the
compressed folder to a new uncompressed folder.
Note that you do have to extract the files - do not just double-click the file. More information here.

MySQL Database Setup


As of v0.2.0, a MySQL database is required for the server and map editor to run. The following is a
basic run-through on how to get your server ready.

What is MySQL
MySQL is a powerful multi-purpose database. It runs as a service on your computer, which means that
it will work in the background when your computer is running. Don't worry, it will use very little RAM
and no CPU if you don't use it. MySQL works by getting a query string from the client, then returns the
requested information. It uses a very simplistic language format for the query, but has very powerful
functions. Many games today uses a MSSQL or MySQL database, from Trickster to World of Warcraft.
Since vbGORE version 0.2.0, MySQL has been added to replace the editors and hard to work with file
formats. MySQL also allows for remote connections so you can edit from other computers without
moving any of the data, along with being able to read the information through web pages.

Downloading MySQL
A few files must be downloaded first. When you click on each link to download do not worry about any
of the other files that come up. Close out of the windows. You will get to them later.

1. Click to download MySQL. If and only if this download does not work for you, you may try an
alternative download from the MySQL 5.0 site here.
2. Click to download ODBC 3.51. If and only if this download does not work for you, you may try an
alternative download from the ODBC 3.51 site here.

Return To Help Topics


3. Click to download SQLyog. A MySQL GUI will be required. We recommend SQLyog for a free
GUI, but if there is another you prefer to use, please feel free to do so. This guide will refer to using
SQLyog, though.

Installing MySQL
1. The first thing you need to do is to remove ALL traces of MySQL if you installed it before. First,
remove it with Add / Remove Programs in the control panel. After that, go to where MySQL was
installed (default "C:\Program Files\MySQL") and delete MySQL manually.
2. Extract the ZIP file and run the MySQL setup.
3. After running the application, you should see the following page. Just hit Next through the pages -
the default settings are all you need.
4. When the installer finishes, make sure you tick the Configure the MySQL Server now box ticked,
then press Finish. If you don't configure the server now, you can always configure it later. A shortcut
should be placed in your start menu to it with a name similar to Configure MySQL instance.

Configure MySQL
1. A new application should pop up. Click Next to reach the following page, then tick the Detailed
Configuration option.

Return To Help Topics


3. Select developer machine.

Return To Help Topics


4. Select Multifunctional database.

5. Click Next.

Return To Help Topics


6. Select Decision Support.

7. If you want to ever connect to your database remotely (from other computers), select Enable TCP/IP
Networking. If you only want to run it from the same computer the game server is on, you can leave
this unticked. It is recommended you do tick it for later usage.

Return To Help Topics


8. Select Standard Character Set.

9. Select Install As Windows Service. The service name does not matter - they all do the same. This will
allow MySQL to run in the background every time Windows loads.

Return To Help Topics


10. Enter in the password for your database. If you enter in the password as test, you do not have to
follow the Set Your Database Password step

11. Click the Execute button.

Return To Help Topics


12. You may receive an error about a firewall. If pressing Retry a few times does not work, disable any
firewalls you have running.

If you have installed it already and reinstalled it you have to do several steps. Go to start>All
program>Mysql>MySQL Server Instance Config Wizard
Double Click on it and start it up. Just go through the default settings. Also, don't forget to change your
password(even if it is the same) during the config wizard.

Installing ODBC Connector


1. Run odbc351.msi.
2. Follow the steps, using the default settings.

MySQL Videos
Installing MySQL Video
Configuring MySQL
Videos By NotExistant (Arie Miller) sorry for bad quality I blame windows movie maker.

Return To Help Topics


MySQL GUIs
I suggest using SQLyog, which is free. Below is how to set it up.

1. Run sqlyog603.exe that was downloaded earlier.

2. Continue through the setup using the settings of your choice.


3. Configure the MySQL connection values as displayed below. In the password field, enter the
password you entered into the MySQL Instance Configuration.

Return To Help Topics


4. Now we have to import the database information that comes with vbGORE. Right-click on the left
panel and select Create Database. Name your database vbgore, all lower case.

5. Right click the vbGORE database and click Restore from SQL dump browse for vbgore.sql and
press execute. After you press execute once, click close. Pressing execute will give you an error that
simply means you have already imported the data.
Important: If you get an error message saying "Error Code: 1050 - Table 'banned_ips' already exists"
or something like that, it means that you already imported the data either before, or you just did.
SQLyog is strange on its way of reporting a successful import, so it is very easy to do it without
realizing it. If you get this message, just move on, since you're done with this step.

Return To Help Topics


More Videos
setting up SQLyog video by Arie Miller

Return To Help Topics


Set Your Database Password
NOTE: You only need to do this step if you haven't set your password to test.
This allows you to set any password for your MySQL Game Database. To set the password, open up
the Server.ini file (preferably in notepad, wordpad, or a similar file), located in the ServerData folder (\
ServerData\Server.ini). From there, enter the same password you entered in the MySQL Server
Instance Config Wizard into the Password line of the file. In the file, the line looks similar to this:
//Password for the username specified above for the database - same as the password
entered into the MySQL Instance Config
Password=test

Troubleshooting
Cannot create Windows service for MySQL
If you are getting an error message for MySQL 5.0 during the execute procedure, and the error is
"Cannot create Windows service for MySql. Error: 0" the usual problem is the install directory,
C:/Program Files/..... The space between Program & Files also prevents MySQL from creating/starting
service, so install MySQL server in C:/ itself (ex: C:/MYSQL).

Access Denied
Access denied simply means that the username and password you entered for the database was
invalid. This is a very common error people have on their first time trying to run vbGORE. The
password is the same password you entered into the MySQL Instance Configuration after
installing MySQL. The username is often left as root for the primary account.
These values can be changed in the server's configuration file, which is found in
root/ServerData/Server.ini on the following lines:
//MySQL account username (default is "root")
User=root

//Password for the username specified above for the database - same as the password
entered into the MySQL Instance Config
Password=test

If you try to save the file and you can't you'll have to do one of the steps below:
1. Ask the administrator of the computer to give you privileges.
2. Move the location of the vbgore folder to somewhere else like the desktop.

Return To Help Topics


Can't Connect to MySQL Server
A Can't connect to MySQL server error often means one of the following:
• The MySQL service is not running or not installed
• An invalid server IP or port was entered
• A firewall or unopened ports (port forwarding) prevent access to the server (remote only)
By default, MySQL is set up to run on the same computer as the vbGORE server. If this is the
configuration you are using, too, then you should not have to worry about changing the IP or Port for
MySQL. If you are running MySQL remotely, then you will need to change these values. These values
can be changed in the server's configuration file, which is found in root/ServerData/Server.ini on the
following lines:
//External IP of the MySQL host ("75.197.223.6" for hosted locally [on the same
computer as the server])
Host=75.197.223.6

//Port of the MySQL database (default is "3306")


Port=3306

Keep in mind that the Host requires the external IP, not internal. You can get this IP by going on the
host machine and going to WhatIsMyIP.org or other similar sites if you do not already know the IP.
If you are hosting locally, the problem is most likely that you do not have the service running. The first
step is to make sure you have installed MySQL and run the MySQL Instance Configuration
successfully. If the service will still not load, you can load it manually through:
Right-click 'My Computer' -> 'Manage' -> 'Services and Applications' -> 'Services'
Find your MySQL service in this list (name usually starts with 'MySQL'), right-click it and click 'Start'

Unknown Database
Unknown Database means that you have connected to MySQL, but the database you specified does not
exist. By default, this is the vbgore database. Make sure that you have imported the vbgore.sql file into
the database with SQLyog, Navicat or your MySQL GUI of preference.
The name of the database can be changed in the root/ServerData/Server.ini file on the line:
//Name of the MySQL database (default is "vbgore")
Database=vbgore

Driver Not Found


Data source name not found and no default driver specified means that you did not install ODBC, or
your installed an invalid version of ODBC. Please make sure you download and install ODBC v3.51.
Any other version of ODBC is not guaranteed to work.
ODBC allows vbGORE to connect to the MySQL server. This is a required application on any

Return To Help Topics


computer trying to connect to MySQL with vbGORE. That means any computer running the map
editor, server, or any other vbGORE program / tool that uses the database must install this. You do not
need to include this for general usage downloads, though, since only the server and development tools
connect to the database.

Table Doesn't Exist


A table doesn't exist error means that one or more of the tables required by vbGORE could not be
found in your database. The most common cause of this is failure to import the vbgore.sql file into the
database. Make sure that you have imported the vbgore.sql file into the database with SQLyog, Navicat
or your MySQL GUI of preference.

Starting The Game


Getting back to installing vbGOREmania... To start the game, you will first need to load the server, as
stated above. The server is located in the default folder with all the other exes and has an icon of a
black computer and is named GameServer.exe. Once that is loaded up (should take a second or two to
load at most), load up the client, GameClient.exe.

Register OCXs And DLLs


Sometimes there are issues with getting the *.ocx and *.dll library files to install properly. For
Example, some report seeing this error:

Run-time error '339':

Component 'Socket.ocx' or one of its dependencies not correctly registered: a file


is missing or invalid

If you do, then please copy your files from the Libraries folder (comes with the vbGORE(mania)
download) to your System32 folder (default C:\Windows\System32\). If you do not have a System32
folder, use your ...\System\ folder. If this does not work, you can try copying all the files into the same
folder all the EXEs are. If both of those fail, please read the below.
Those who get the error said above with a missing component do not have the file in the correct path or
you need to register it. Many installation programs can do this automatically, but with archived (zip,
rar, 7z, tar, etc) files that you extract, these files are not registered automatically and may not be
recognized automatically.
To register a file, you first need to find it's path. Most files should be located in ...\Libraries\ so start
with finding that folder. Look for the file that can not be found, then right-click it and click Properties.
In the Properties window, in the 2nd section down, you will see Location. Take the Location and
combine it with the file's name to get the full path. Example:
File path: C:\vbGORE\Libraries\ File name: Socket.ocx Complete file path:
C:\vbGORE\Libraries\Socket.ocx
Take this complete file path and go to Start -> Run to bring up the Run prompt. Enter the following:

Return To Help Topics


regsvr32 "<filepath>"

where <filepath> is the Complete file path you acquired from the method above. When you are
finished, it should look something like this:
regsvr32 "C:\vbGORE\Libraries\Socket.ocx"

Make sure you keep the " " in there so the program knows it is all combined. Once you have that
entered, just press OK or press Enter and the registration should succeed! If it does not, it is more then
likely that you have entered the wrong file path.

Game Client
Learning The Game Controls
The control scheme for vbGORE, I admit, is not the greatest. You can change all the controls through
the source easily enough. In the following section is where you can find all the default controls. It is
important to check it out because it also gives you a better idea of what is in vbGOREmania. Please
note that most of these commands can be executed by the push of a button in the chat window's
command menu.

Movement & Combat / Targeting


The following commands allow the user to move their character and engage in combat.

Movement
walk: left mouse click run: r

Combat & Targeting


Attack: left click on npc

Misc.
Buy from NPC: Right-click NPC vendor, left-click item in item window to buy
Get item description: Right-click item in inventory/vendor window
Set description: "/desc <description>"
Get item off ground: space

Display Options
These commands are all used to modify, use, or display certain menus or displays.
Hide/Show Inventory: Ctrl + w
Hide/Show Quick Bar: Ctrl + q
Hide/Show Chat window: Ctrl + c
Reset GUI Positions: F10
Close Windows: Escape
Zoom View In: NumPad '8'
Zoom View Out: NumPad '2'
Display Mini-map: Tab

Return To Help Topics


Communication Commands
These are commands that can be initiated by any user for communicating with other players in the
world or server a purpose of any communication form.

Talk
Command: Enter
The user may push enter to engage in chat or to enter commands that need to be entered through chat.
When done the user clicks enter again to submit the message.

Read Mail
Command: Right-click Mailbox
Allows the user to check their messages in their mailbox that are sent by other players or admins.

Private Message
Command: "/tell <name> <message>"
Allows you to send a message to given players name so that only you and that user may see the
message you have sent. This is often used for private chats or for messages only desired to be herd by
the two users.

Shout
Command: "/shout <message>"
Sends a message to everyone.

Guild Commands

Guild Chat
Command: "/g <message>"
Sends a message to everyone in the user's guild, if they are in a guild.

Create Guild
Command: "/creatg"
Allows the player to create their own guild. They must not be a part of a guild already.

Leave Guild
Command: "/leaveg"
Makes the user leave the guild they are in.

Invite to Guild
Command: "/invite <name>" Invites a user to join your guild. They must respond within 10 seconds to
join the guild.

Join Guild
Command: "/joing"
Accepts an invitation to a guild.

Return To Help Topics


Assign Rank
Command: "/assign <player> <rank>"
Assigns a rank to guild member.

Found in Game Server → Guilds.bas


GroupRanks(1) = "General"
GroupRanks(2) = "Captain"
GroupRanks(3) = "Lieutenant"
GroupRanks(4) = "Sergeant"
GroupRanks(5) = "Corporal"
GroupRanks(6) = "Recruit"

Guild Meeting
Command: "/gmeet"
Sends an invitation to all players in guild to attend a guild meeting

Attend Guild Meeting


Command: "/attendg"
Accepts invitation to attend guild meeting. Player is teleported to person calling the meeting.

Party Commands
Party's are like temporary groups where you can quest/kill together and share rewards

Party Chat
Command: "/p <message>"
Sends a message to everyone in the user's party, if they are in a party.

Create Party
Command: "/creatp"
Allows the player to create their own party. They must not be a part of a party already.

Leave Party
Command: "/leavep"
Makes the user leave the party they are in.

Invite to Party
Command: "/pinvite <name>" Invites a user to join your party. They must respond within 10 seconds to
join the party.

Join Party
Command: "/joinp"
Accepts an invitation to a party.

Friend Commands

Return To Help Topics


Add Friend
Command: "/ADDFRIEND <friend name>"
Add a friend to your friend list

Remove Friend
Command: "/REMOVE FRIEND <friend name>"
Remove friend from friend list

Add Block
Command: "/BLOCK"
Add player to ignore list

Remove Block
Command: "/UNBLOCK"
Remove player from ignore list

Misc Commands

Who`s Online
Command: "/who"
Lists inside the communication (chat) box what players or users are currently online.

Look Left
Command: "/lookl"
When used your character will look to his/her left.

Look Right
Command: "/lookr"
When used your character will look to his/her right.

Blink
Command: "/blink"
When used your character will blink.

Emote
Command: "/me"
Allows the user to type a message and instead of displaying as something the player said it will display
it as what the users actions are. For example, typing the text:

/hi

Would come out as

<playername> says hi

Return To Help Topics


Emoticon
Command: Keypad number from 0 ~ 9 (not in the keyboard)
Displays images above the user when the listed keys are pressed to show feelings of the player.

View Active Quests


Command: "/quest #"
If # is not specified or is invalid, then a list of the user's active quests is displayed by number and title.
If a valid number is specified in the location of # (ex: /quest 1), the quest title and information is
displayed.

Cancel Active Quest


Command: "/cancelquest #" or "/endquest #"
Cancels a quest as defined by #, where # is the ID of the quest in the list view with the "/quest"
command.

Deposit Gold In Bank


Command: "/deposit #"
Deposits # amount of gold into the bank. Must be near a banker NPC to use.

Withdraw Gold From Bank


Command: "/withdraw #"
Withdraws # amount of gold from the bank. Must be near a banker NPC and have at least # amount of
gold in your bank to use.

Bank Balance
Command: "/balance"
Displays the amount of gold you have in your bank account. Must be near a banker NPC to use.

Trade
Command: "/Trade <name>"
Requests a trade with the player who's name was inserted.

Quit
Command: "/quit"
Closes the client.

Help
Command: "/help"
Brings up the help information, defined in the \ServerData\Help.ini file.

GM Commands
The following commands require the character to be marked as a GM. You need to edit vbGORE's
users table in the database to set a player as GM (GM = 1 for yes, GM = 0 for no).

By default all players start as GMs! To change this open the TCP Modules file in the Servers folder.
Look for line: 'This is for testing purposes only - remove this in any public release!
UserList(UserIndex).Flags.GMLevel = 0 (Change the 1 to 0)

Return To Help Topics


Summon Player
Command: "/sum <name>"
Allows the GM to bring/teleport a player to their location.

Approach Player
Command: "/appr <name>"
Allows the GM to teleport or appear at the location of given player.

Map Warp
Command "/warp <mapID>"
Warps the GM to the map by index <mapID>. The GM is set on the very first non-blocked tile found.

Kick Player
Command: "/kick <name>"
Kicks the player out of the game or in other words disconnecting them from the game at that time.

Raise Player's Experience


Command: "/raise <name> <exp>"
Raises the given players experience (or exp) to the given integer.

Thrall
Command: "/thrall <npcnumber> <amount>"
Summons a number of NPCs by the NPC number. Thralled NPCs do not respawn.

Dethrall
Command: "/dethrall"
Kills all thralled NPCs in the screen.

Set GM Level
Command: "/setgm <name> <level>"
Sets user <name> to GM level <level>.

IP Banning
Command: "/banip <ip> <reason>"
Bans IP <ip> for reason <reason>. The reason must be specified. The IP must follow the format of
x.x.x.x, where x is any number between 0 and 255.

IP Unbanning
Command: "/unbanip <ip>"
Removes the IP ban from IP <ip>. The IP must follow the format of x.x.x.x, where x is any number
between 0 and 255.

Ban List
Command: "/banlist"
Displays a list of every IP and and the reason for the ban. Warning - with a lot of bans, this routine can

Return To Help Topics


become very slow and may even cause a crash!
IP Info
Command "/ipinfo <ip>"
Returns a list of every user who has logged in with the IP <ip> within their last 10 unique IPs they
have logged in from.

Click Warping
Command: "/clickwarp"
Toggles on and off click-warping. When toggled on, right-clicking a tile will warp you to it (or the
closest legal tile if the clicked on is not legal).

Item Search
Command: "/searchitem <name>"
Returns a list of items that contain the characters as written in the parameter <name>. List is ordered
by item ID.

SQL Query
Command: "/sql <query>"
Runs a SQL query as defined by the parameter <query> on the database. Information is reported back
to the GM running the command. Only certain operations are allowed to prevent abuse. By default, the
allowed operations are SELECT, SHOW, DESCRIBE, OPTIMIZE, REPAIR, ANALYZE, BACKUP
and FLUSH.

Kill
Command: "/kill"
Kills the PC or NPC that the user has targeted. Can not be used to kill yourself (to prevent accidental
self-killing). Nothing is rewarded to the GM using the command, nor will NPCs drop items.

Kill Map
Command: "/killmap"
Kills every NPC on the map that the GM using the command is on. Same conditions apply to the
killing as with using the /kill command.

Give Gold
Command: "/givegold <amount>"
Gives the GM <amount> gold.

Give Object
Command: "/giveobj <objindex> <amount>"
Gives the GM <amount> of object by index <objindex>. Recommended to use the /searchitem
command to find the object index.

Give Skills
Command: "/giveskill <username> <skillID>" (or /givespell)
Gives the user by name <username> the skill by ID <skillID>. The User_GiveSkill function is
used, so the same restrictions still apply that are in that, which is that the user must meet the valid

Return To Help Topics


conditions to have the skill.

System Requirements
vbGORE is developed under Visual Basic 6, so it is bound to Windows-based operating systems or
using Wine under Linux. All information listed below are minimum requirements (and it can be
running slow, e.g.: run the server on a 3000mhz is very different than run the server at a pc with
minimum requirements).

Client Side:
Operating System: Windows 98 or later
Processor: 500mhz
RAM: 128 MB
Graphics Card: 16 MB with Direct3D 8 support
DirectX: 8.0 or higher
Disk Space: 50 MB free disk space

Server Side:
Operating System: Windows 98 or later
Processor: 800mhz (300mhz if you don't include the mysql and ODBC at the same computer)
RAM: 64 MB
Disk Space: 200 MB free disk space (includes space required for MySQL)
Database: MySQL 5.0 and ODBC 3.51

Changing Emoticons
An emoticon is a representation of emotions through characters or icons, such as :) and :(. In vbGORE,
emoticons are used to display a graphical animation of emotion above the character's head who used
the emoticon. These emoticons can be used on NPCs, too, to bring life to them.

Emoticons can be displayed, by default, by using the a combination of Control (Ctrl) + a number 0~9,
not using the numpad. Current emoticons are: 1- ... | 2- ! | 3- ? | 4- Red ! | 5- Heart |6- Cluster of hearts
| 7- Broken heart | 8- Spoon & Fork | 9- Turkey Leg | 0- !? | 12/16/07

Adding emoticon graphics is just the same as adding any other graphic to the engine.

Programming In Emoticons
The packet ID is handled by User_Emote. Do not get this confused with Comm_Emote, which is

Return To Help Topics


typing an emote. The packet sent to the server is filled simply by the ID of the emoticon. The server
receives it, and dishes out a packet to every PC in visible range the emoticon by sending the Emoticon
ID and the Character's Index (CharIndex).
First you must assign an Emoticon ID (EmoID) to the emoticon. Just like SkillIDs, StatIDs and
PacketIDs, these should be the exact same values on both the server and client. Make sure you also
update NumEmotes to the highest value of the EmoIDs. The EmoIDs are set in the InitDataPackets sub,
along with the PacketIDs, StatIDs, etc.
The Emoticon ID has the GrhID set in the Data_User_Emote sub on the client. Find the EmoID you
want, and apply the appropriate GrhIndex.
That is about all there is to do. In shorter, more organized terms:
• Create the GrhIndex(s) for the emoticon
• Update the Grh.Dat file on the client
• Add a new variable in EmoID on both client and server
• Set the EmoID value to an unused value on both the server/client
• Update NumEmoticons to the highest EmoID used
• On Data_User_Emote on the client, find Select Case EmoticonIndex and follow the same
format already used and set the GrhIndex to the appropriate value

Message Translations
The Messages in vbGORE refers to the messages that the client displays. These messages are for the
most part constant, sometimes with one or multiple variables in them in defined locations.
For example, the message:
Bandit appears to be no longer weakened.

Would be written in the message file as:


<npcname> appears to be no longer weakened.

When the server wants to send the text to a client, instead of sending the whole text as displayed in the
first example, a number is set along with any required variables. In our example, the number 1 will be
sent, followed by a string (being the NPC's name, "Bandit").
To edit the messages (or translate it), you need to work with the <yourlanguage>.ini that is located in
data/messages folder. It's important to remind that if you want to translate to a language, just copy the
original file, rename it, open, edit and save it.

You ultimately want to reach as large as a player-base as possible. This may mean encountering
players who speak a different language. I recommend using either Google Translator or WordMonkey.

How To Edit

Return To Help Topics


The message files have some very important rules to follow.
[MAINtag
This tag must remain at the very top as-is. Do not translate.
NumMessages tag
This tag tells how many messages there is. This won't ever need to be changed when doing
translations. This value should reflect the highest number value in the file to the left of the = sign.
Do not translate.
In-text tags
There are multiple in-text tags, such as <exp>, <name>, and <amount>. These can be moved to
any part of the text needed, but the tag themselves must never change, so do not translate these!
They are designed to be moved to appropriately fit the translation.

The following rules will not break or change the way the translation functions, but are still important:
Grammar / Punctuation
Use as proper grammar and punctuation as possible. These translations are designed to be good
translations, not the quality an automatic translator gives you.
Number order
Please leave the number order in ascending order for organizational purposes.

The following are little tips and facts about the system that would be helpful to know:
Comments
Comments are signified by the -- in front of them. This is here just for reading purposes, though.
Please leave them in tact. Comments do not have to be translated, and it is recommended you do
not translate them unless you want to.
Getting stuck
If you get stuck on a translation, just skip it and make clear note that you did not translate it.
Unfinished translations should have a (Unfinished) tag in their header (ex: English
(Unfinished) ) to show that they are unfinished. At the very start, before the <pre> tag, write what
is left to be translated.
Formatting the code
Please use the <pre> and </pre> on this page at the very start and very end of the language
translation. This will put a box around the code. For an example, just refer to the currently
existing translations.

Server

Adding Server Messages


Server messages are referred to by their ID and the message itself is stored on the client. This allows
for less bandwidth usage, along with more message processing (such as multiple language support).
Although you do not have to do this with messages, it is recommended that you do for as many as you
can.

Return To Help Topics


Message File
The first step is to go into the \Data\Messages\ folder and add your message to the language file (such
as english.ini). The number on the left is the message ID while the text on the right is the message
itself. The message ID must be unique from every other ID in the list. Messages support variables,
which are often denoted by <> tags, but these are not automatic - you must do extra work to support
them. For example:
135=You lost <amount> <objname>(s).

<amount> and <objname> are replaced when the client reads the message from the server, and the
server must pass additional values.
After you add your messages, update _nummessages.ini with the highest message ID.
== On the server ==a
There are two ways messages are sent - either through a pre-cached byte array or by building the
message packet. Pre-cached messages can only be done for messages with no extra parameters, but are
faster and easier to write.

Pre-Cached
To add a message to the pre-cached message list, search the code for:
Const cMessages As String =

Anywhere in this huge string list, add the ID of your message. The code will take care of the rest for
you. You can now make a reference to that message by using:
cMessage(ID).Data()

For example, this:


Data_Send ToIndex, UserIndex, cMessage(99).Data

Will send message 99 to the user. This is the exact same as using this code:
ConBuf.PreAllocate 2
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 99
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer

But using the cached message is a lot faster since the byte array is already made and the conversion
buffer doesn't have to be used as a medium to create it.

Non-Cached
Messages that have parameters must be created this way because of the extra fields they offer. You can
pass as many parameters of any type you want, but the client must know what to grab. For example,

Return To Help Topics


you can send a message with no parameters:
ConBuf.PreAllocate 2
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 99
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer

Or a message with some parameters:


ConBuf.PreAllocate 5 +
Len(ObjData.Name(QuestData(NPCList(QuestNPC).Quest).AcceptReqObj))
ConBuf.Put_Byte DataCode.Server_Message
ConBuf.Put_Byte 63
ConBuf.Put_Integer QuestData(NPCList(QuestNPC).Quest).AcceptReqObjAmount
ConBuf.Put_String ObjData.Name(QuestData(NPCList(QuestNPC).Quest).AcceptReqObj)
Data_Send ToIndex, UserIndex, ConBuf.Get_Buffer

Keep in mind you will have to denote where these parameters go in the message file, such as using <>
tags like vbGORE does by default. As long as the client knows what parameters are there, and what
they mean, you can send whatever you want.

On The Client
All the server message handling that you need to worry about happens in Sub Data_Server_Message.
For your message, add a new Case anywhere you want in the Select Case block, with the case
number being the ID number of your message.
If you do not have any parameters, like message 99, you can just go straight to handling the message.
Usually, this is just displaying the message in the message box:
Case 99
Engine_AddToChatTextBuffer Message(99), FontColor_Info

But if you have parameters, you must grab them out first before doing anything:
Case 63
Int1 = rBuf.Get_Integer
Str1 = rBuf.Get_String
TempStr = Replace$(Message(63), "<amount>", Int1)
Engine_AddToChatTextBuffer Replace$(TempStr, "<name>", Str1), FontColor_Info

As you can see, for each parameter, there is a Replace$() function. The unaltered message starts in
the variable Message(63). The altered message, the one that holds are variable replacements, is held
in the TempStr variable. As you can see, you simply just enter in the variable name you wish to
replace from your message, and the variable you wish to replace it with. For example, <amount> is
being replaced with Int1, which was our first parameter.

Monitoring Bandwidth
While adding and removing features, it is easy to unintentionally add extremely large packets or even
flood your own packets without even realizing it. It is also good to get an estimate on the rough
bytes/sec bandwidth you will have with a certain amount of players on so you can get a better idea on

Return To Help Topics


what kind of server bandwidth you will be using.

Setting Up Wireshark
First off, it is recommended you do this with a public server, so set your server IP public and connect to
your server through the client with your external IP. Now, download Wireshark from the Wireshark
Download Page and install it. Load the program and click on the 2nd button on the toolbar that should
be captioned Show the capture options.... Next to the Capture Filter button, add the following line:
src port 10200 and src host <hostip>

...where <hostip> is your external IP. Now start capturing packets by pressing Start.

Packet Meanings
ACK
ACK stands for acknowledgment, which is part of the TCP structure. When a packet is sent, the
receiver of the packet sends and ACK back to tell that the packet was successfully received.
PSH
PSH is for Push, which is a packet that has data attached to it.
Len
Displays the amount of data sent in the packet. Just another way to see amount of data sent, but
from the Info bar.
Data
This is the actual information send from the server. As you notice, in comparison, the data to
overall bandwidth usage ratio if very, very bad, which is why we try to send packets as little as
possible.

Viewing Bandwidth Usage


Now for the fun part. To view the bandwidth usage, go to Statistics then Summary. At the bottom, you
will see the average bytes / sec and average MBit* / sec.
*Not to be confused with MByte, there are 8 bits in a byte, so to go from MBit to MByte, just divide by
8.

Optimizing Packet Headers


Packets must include a header telling it where to go. For UDP, this header is around 8 bytes, while TCP
headers are from 20 to 24 bytes (depending on what options are used in the packet). TCP, though
slightly slower and bulkier, gives a lot more reliability. With UDP, you have to assume a packet may be
dropped at any given time.
Combined with the 20 byte TCP header, there is the IPv4 header, which is 20 bytes. When IPv6 comes
out, it will use 40 bytes instead of 20. So we are looking at a 40 byte header in a best case scenario, and
64 bytes in worst case (though IPv4 is more popular then IPv6 at the moment). These values add up
quick, and tower over most any vbGORE packet in size.

Return To Help Topics


The Solution
So what is there to do to fight against these packets? Well lets use a nice little analogy first. Compare
throwing ten 1-pound rock or one 10-pound rock. You have the constant force required to move your
arm for the throwing, so throwing 10 rocks, although each throw is easier, requires more force in the
long run. The same is for packets - it puts more stress on the server to send a large packet, but overall is
less in comparison to the multiple small packets.
So what is the solution? The most obvious one - send less packets. Smash together as much as possible
then throw it to the client all at once. Problem with this, though, is it takes time to get the information
to pack together. You cant just send one big packet to the client every second - that is what we like to
call 1000ms of intensively annoying lag. It can be quite confusing walking around, and seeing all the
NPCs jump around once every second. But on the other hand, theres some packets we really don't care
about. That is where the priorities comes in. But first off, the buffering.

Packet Buffering
vbGORE uses a custom buffering algorithm to smash together all those little packets under one header
and send it all at once, making the most out of the header size (along with it is just overall faster).
When you use Data_Send, it is actually going into a buffer of the users you specify for it to send to. It
is not until the end of the update loop for the user that the data is actually sent.
In v0.2.1, there is a "global wait" constant that can be set which will forcibly buffer for a certain period
of time. Such as if your server was running at 1000FPS, sending packets every millisecond is a total
waste, so you can set the value to 50, so it is like your packets are running at 20 FPS. That may sound
low, but think of any time you have played a game and you had a ping of 50. Did you complain? Hell
no! You were probably as giddy as a schoolgirl for such a low ping!

Packet Priorities
The packet priority system was invented (well maybe not invented, but have never heard or seen such a
system before) to combine those low-priority packets with those important packets. Just because they
are low-priority, it doesn't mean we don't want to send them, though - we are just not worried about the
time it takes for them to get there. It can be very tricky to decide what you want to use, and using
PP_None can be dangerous. Though this may help a bit:
Note that PP_None will always, as a last resort, end up attaching to the ping packet just since the
way it is structured (since the ping packet is PP_High). Be very careful with PP_None if you
remove the ping or lower the time!
PP_High
Use this for most all the packets. Try and think of what it'd be like if the packet got there about a
second later. What would it be like? If it was the server telling the client to play a sound or that a
character attacked, it wouldn't look good if it took over a second to show up, would it? No... no it
would not.
PP_Low
This will be your most commonly used "unimportant" packet state. Try to think when making a

Return To Help Topics


packet, does it need to get to the user as soon as possible? Can they wait at least a second? Such
as if they were to equip new armor, is it really vital if they can see the stat change within a
second?
PP_None
This is the hard one. How vital is the information? Can it wait for a few seconds? Will the user
notice if it takes a while to get to them? The best example is the receiving new mail message -
unless you are told that you were just sent mail by the user, you wont notice if it takes an extra 1-
10 seconds to get to you. Use this with extreme caution.

The packet priorities in vbGORE is made very simple for the user. In the Data_Send routine, there is an
optional parameter at the end to set the packet priority. You can just ignore this value and it will
automatically be set to PP_HIGH.

Packet Structure
The packets for vbGORE are written in a byte array. A byte is the smallest sized variable you can have.
A byte array simply means a series of bytes put together. In a way, a string is like a byte array. Each
value of a byte can be 0 to 255, while each character in a string can be an ASCII character with the ID
of 0 to 255.
vbGORE makes creating the byte arrays easy for you with the DataBuffer class module. All you have
to do is get information out the same way you put it in. Each packet is structured, broadly, in the
following manner: <DataCode><DataInformation>
Your DataCode is a value from 0 to 255 which states what kind of function will take place. You can
recognize these functions by their Sub name, which start with "Data_" and end with the Datacode's
name. These functions can be anything - walking, casting spells, talking, etc. They simply just tell the
other computer what kind of packet it is.
According to the packet type, you have to get the data out accordingly. For example, if you have a
Move packet received on the server (that is, the DataCode = User_Move), your DataInformation is and
always will be one byte which states the direction the user is moving.
It is important you sync up the information of the Client and Server. You must never read data out of
the order you send it. I have made things easier for you by writing how every packet is structured under
the packet's recieve module (ie Data_Comm_Talk). The information looks like this:
'*********************************************
'Send data to chat buffer
'<Text(S)><FontColorID(B)>
'*********************************************

The first line tells what the sub does. In this case, we are using Data_Comm_Talk. As it says above,
this sends the recieved data to the chat buffer. The arguments the client sends are Text which is a String
and FontColorID which is a byte. You can tell if it is a string or byte by the (S) and (B). Below is the
list of the different identifiers:
(B) = Byte

Return To Help Topics


(I) = Integer
(L) = Long
(S) = String
(S-EX) = StringEX
Note that you do not see the DataCode in here - this has already been removed in the
Sox_OnDataArrival sub since you do not need it anymore.
As for packing data, it is as simple as using the following commands:
Put_Byte - packs a byte into the buffer
Put_Integer - packs an integer
Put_Long - packs a long
Put_String - packs a string 1 to 255 characters long
Put_StringEX - packs a string 1 to 65,535 characters long
These are all self-explanatory besides String and StringEX. The difference between these two is their
identifier size. Strings are variable-length, unlike a byte or long, so you have to pack an extra variable
to say how long the string is. Put_String packs a byte before the string to say how long the string is
(thus why a max of 255 characters long) while StringEX packs an integer (thus why a max of 65535
characters long) to identify how long the string is. This is all handled by the Databuffer, though, so you
only have to remember that String is short strings, StringEX is long strings.
To receive the data you send, just use Get in the same order as you used Put for that DataCode. Make
sure you always place the DataCode in the buffer before you place in any other information.

Database
If you have have not already done so, please Setup the MySQL Database before viewing this section.

Field Descriptions
Note that there are editors (such as NPC Editor or Quest Editor), mentioned earlier, that you can use to
edit these fields with. If you are unsure of what your are doing, I recommend using the editors.

Banned Ips
The banned_ips table stores information on IP banning, along with the reasons why the IP was
banned. This only holds active bans, so any IPs listed in here will not be allowed in the game.
ip
Holds the banned IP.

reason

Return To Help Topics


Holds the reason why the IP was banned. This can contain any information you wish.

Mail
The mail table stores all the information on the messages currently in the game. When mail is deleted
from a user, it is deleted from here, too.
id
The unique identifier of the message. Using these numbers on the user characters, the game refers
to what mail they have. For example, if a user has 100 in one of their mail indexes, it will point to
the mail with the id of 100.

sub
Subject of the message.

by
The name of the player who created the message. Used for display purposes only when reading
the mail.

date
The date the message was created on.

msg
The body of the message.

new
If the message has been read or not by the receiver. 1 for is new, 0 for is not new.

objs
Holds information of all the objects in the mail. The first number, represents the unique ID of the
object (see objects). The second number represents the value of the item (or how many items).
Object parts (amount and ID) are split by a space, while objects as a whole are split by a line
break (vbCrLf, aka enter).

mail_lastid
The mail_lastid table is just used in conjunction with the mail table for writing mail.
lastid
Holds the last mail ID written to. This is a faster alternative to using a descending sort on the mail
to find the highest ID. Is only used for writing mail.

NPCs
The npcs table holds templates of what to create NPCs from. After being loaded from here, they can be

Return To Help Topics


altered in-game without affecting any other NPCs.
id
The unique ID of the NPC (this is what NPCNumber in the code often refers to).

name
The name of the NPC.

descr
The description displayed when right-clicking the NPC.

ai
States which AI algorithm to use in the NPC_AI sub located in the server code.

chat
States the chat information the NPC uses. This refers to the NPC chat information in the
\Data\NPC Chat\ folder. Set to 0 to not use NPC chat.

respawnwait
The time it takes the NPC to respawn after killed, in milliseconds.

attackable
Tell us, if the NPC is attackable or not. 1 is Yes, 0 is No.

attackgrh
The GRH value of the attack.

attackrange
The range of the attack, used for ranged attacks, e.g with bows and arrows. If this value is 0 or 1,
the attack will be marked as a melee attack. If not, the range of the attack is based on tiles.

projectileroatespeed
How fast the projectile grh rotates on the client's screen (in no specific unit of measurement), if a
projectile.

hostile
If the NPC hostile or not (goes and attacks players). 0 is No, 1 is Yes.

quest
The quest ID of the NPC. 0 is no quest, any other number refers to the quest with the
corresponding ID in the quests table.

drops
The objects that the NPC drops when it dies. The first value is the object ID, second is the
amount of the item that is dropped, and the third is the chance, in percent, that the item will drop.

Return To Help Topics


give_exp
The amount of Experience points, given when the NPC is killed

give_gold
The amount of Gold dropped, when the NPC is killed

objs_shop
The objects that the NPC sells. If this field is set to an empty string, the NPC will not act as a
vendor. Anything other value has to follow this format: The first value contains the ID of the
object sold, while the second value contains the amount of the objects in stock in the store (use -1
for infinite to ignore this feature). Each field is separated by a space, and each object is separated
by a line break.

char_hair
Holds the hair paper-doll values used on the NPC. Refers to the values found in \Data\Hair.dat.

char_head
Holds the head paper-doll values used on the NPC. Refers to the values found in
\Data\Head.dat.

char_body
Holds the body paper-doll values used on the NPC. Refers to the values found in
\Data\Body.dat.

char_weapon
Holds the weapon paper-doll values used on the NPC. Refers to the values found in
\Data\Weapon.dat.

char_wings
Holds the wings paper-doll values used on the NPC. Refers to the values found in
\Data\Wings.dat.

char_mount
Holds the mount paper-doll values used on the NPC. Refers to the values found in
\Data\Mounts.dat.

char_shield
Holds the shield paper-doll values used on the NPC. Refers to the values found in
\Data\Shield.dat.

char_heading
Holds the default heading the NPC is facing by numerical value. 1 = North, 2 = East, 3 = South, 4
= West, 5 = North-East, 6 = South-East, 7 = South-West, 8 = North-West.

Job
If AI is 10 (Job), what job menu to show?

Return To Help Topics


Combat Level
If NPC can attack, what is it's combat level (displayed next to name above head)

char_headheading
Holds the default head heading (direction the NPC's head faces) by numerical value. Refer to the
above for the values.

stat_hitrate
Holds the hit rate of the NPC's attack. The higher the hit, the more likely the hit is to land. This
value is held in the server under the Agility stat, since the NPC does not use the Agility stat by
default. By default, the user's hit rate is calculated by Agil + (Str \ 4).

stat_mag
Holds the NPC's magic stat value which is used in calculations of magic power and damage. This
value works the same as the user's magic value, but is not modified by stats or items like the user.

stat_def
Holds the NPC's defense value, which determines damage reduction upon being attacked by
normal attacks. Magic attacks can use this value for reduction if they choose to do so. This value
works the same as the user's defense value, but is not modified by stats or items like the user.

stat_speed
Holds the NPC's speed value, which states how fast they move. This value works the same as the
user's speed value, but is not modified by stats or items like the user.

stat_hit_min
Holds the minimum hit damage the NPC does. This value works the same as the user's min hit
value, but is not modified by stats or items like the user.

stat_hit_max
Holds the maximum hit damage the NPC does. This value works the same as the user's max hit
value, but is not modified by stats or items like the user.

stat_range_min
Holds the minimum hit damage the NPC does with range attacks. This value works the same as
the user's min hit value, but is not modified by stats or items like the user.

stat_range_max
Holds the maximum range damage the NPC does with range attacks. This value works the same
as the user's max hit value, but is not modified by stats or items like the user.

stat_hp
Holds the maximum health the NPC has.

Return To Help Topics


stat_mp
Holds the maximum mana / magic the NPC has.

stat_sp
Holds the maximum stamina the NPC has.

AirBonus, EarthBonus, WaterBonus, and FireBonus


Holds the NPC's elemental bonuses

Objects
id
The unique identifier of the object (points to the array index in the server's ObjData() array).

name
The name of the object.

price
The price of the object when purchased from a shop. Price when selling to a shop follows a
reduction equation based off of this value.

objtype
States what type of object it is. Each type is handled different. Only one object from each type
can be equipped at once (if it can be equipped). The object types can be found in the server's
Declares module for constants starting with OBJTYPE_.

• 1 – Use Once: After each usage, the item is lost. Common example is potions.
• 2 – Weapons: Set in the weapon slot of the character.
• 3 – Body armor: Set in the armor slot.
• 4 – Wings: Set in the wings slot.
• 5 – Use Infinite: Same as Use Once minus the removal after usage.
weapontype
If the object is a weapon (default value 2), then the type of weapon has to be specified. Although
not used in the vbGORE demo, it can be used to apply to class limitations and have different
modifier values. For example, a staff could be for mage only and the damage be based off of
Magic, while a sword can be for a warrior only and the damaged based off of strength. The
weapon type value and names can be found in the server's Declares module under Enum
WeaponType.

• 0 - Hand
• 1 – Staff
• 2 - Dagger
• 3 - Sword
• 4 - Throwing
weaponrange

Return To Help Topics


If the weapon is a Ranged weapon, this is length of how far the ranged weapon can go in tiles (32
pixels). Measured by absolute value using the distance formula.

classreq
Holds the class required to use the object. The values are stored bitwise, so to restrict multiple
classes, you have to use Class1 OR Class2 OR Class2... The values used are the ones set in the
ClassID type.

grhindex
Graphic of the item as shown in the inventory and on the ground.

usegrh
The objects Grh value, which is used to determine what Graphic the item will be represented by.
For "Use Once" objects, an graphic is displayed when used. For ranged weapons, it is the
projectile of the weapon (ninja star, arrow, bullet, etc). For melee weapons, it is the slash of the
weapon.

usesfx
The sound effect played when the object is used. If it is a weapon, it is when an attack is made.
For a use-once object, it is when the object is used.

projectilerotatespeed
If the weapon is a projectile or shoots projectiles (weaponrange > 1) and usegrh is defined, this
defines how fast the projectile rotates. Useful for throwing projectiles like ninja stars.

stacking
States how much the object can be stacked up. For non-stacking items, such as weapons and
armor, set the value as 1. Any value lower than 1 is reverted to the server default limit, which by
default, is 100 (specified in Const MaxObjAmount)

sprite_body
The GRH value, which show the objects Body Value. Used for paper dolling. Refer to the .dat file
of similar name (in this case, Body.dat) in the \Data\ folder. '-1' equals no graphic

sprite_weapon
Same as 'sprite_body', except for the weapon

sprite_shield
Same as 'sprite_body', except for the shield

sprite_mount
Same as 'sprite_body', except for the mount

sprite_hair
Same as 'sprite_body', except for the Hair

Return To Help Topics


sprite_head
Same as 'sprite_body', except for the Head

sprite_wings
Same as 'sprite_body', except for the Wings

replenish_hp
The amount of Health Points it restores

replenish_mp
The amount of Magic points it restores

replenish_sp
The amount of Speed points it restores

replenish_hp_percent
The percent amount of Health Points it restores. Max value is 100.

replenish_mp_percent
The percent amount of Magic Points it restores. Max value is 100.

replenish_sp_percent
The percent amount of Speed Points it restores. Max value is 100.

stat_str
The amount of Strength Points it adds to the player.

stat_agi
The amount of Agility Points it adds to the player.

stat_mag
The amount of Magic Points it adds to the player.

stat_def
The amount of Defence Points it adds to the player.

stat_speed
The amount of Speed Points it adds to the player.

stat_hit_min
The Minimum amount of HP it can take from a NPC, when attacked.

stat_hit_max
The Maximum amount of HP it can take from a NPC, when attacked.

stat_hp

Return To Help Topics


The amount of Health Points it adds to the player.

stat_mp
The amount of Magic Points it adds to the player.

stat_sp
The amount of Speed Points it adds to the player.

stat_exp
The amount of Expirence Points it adds to the player.

stat_points
The amount of Stat Points it adds to the player.

stat_gold
The amount of Gold it adds to the player.

req_str
The required amount of strength to use the object.

req_agi
The required amount of agility to use the object.

req_mag
The required amount of magic to use the object.

req_lvl
The required level (stat ELV) to use the object.

AirBonus, WaterBonus, EarthBonus, & FireBonus


The elemental bonuses provided by item

NPC_Spawn
Index Of NPC to Spawn (For Furniture Items)

Quest
id
The unique ID of the quest

name
The name of the quest

Return To Help Topics


redoable
Tells us if the Quest can be done again or not. 0 is for no, 1 is for yes.

text_start
The text shown in the Chat Box, when the player wants to start this quest.

text_accept
The text shown in the Chat Box, if the quest is accepted by the player.

text_incomplete
The text shown in the Chat Box, if the quest has been declined or failed by a player.

text_finish
Text shown in the Chat Box, if the quest has been fully completed by the player.

text_info
The information describing the quest when the user requests the quest information while having
the quest in their active quests list. By default, this can be done by typing /quest to view your list
of quests, then /quest #, where # is the ID of the quest in the user's list.

accept_req_level
The minimum level the user must be to accept the quest. The user must be this level, or higher.

accept_req_obj
The object index of the object the user must have to accept the quest. Set to 0 to not require
objects.

accept_req_objamount
If accept_req_obj is > 0, then the user must have more than or equal to this amount of the object
to accept the quest.

accept_req_finishquest
States the ID of the quest that must be finished before this quest can be accepted. Can be used to
make chains of quests. If value = 0, it will be ignored.

accept_reward_exp
The amount of experience the user gains when accepting the quest. Set to 0 for no accept
experience reward.

accept_reward_gold
The amount of gold the user gains when accepting the quest. Set to 0 for no accept gold reward.

accept_reward_obj
The object, by object index, the user receives when accepting the quest. The
accept_reward_objamount value must be set as > 0 for this to be used.

Return To Help Topics


accept_reward_obj
The amount of object as defined in accept_reward_obj the user receives when accepting the
quest. The accept_reward_obj value must be set as > 0 for this to be used.

accept_reward_learnskill
The skill the user learns upon accepting the quest. Value defined by SkID (Skill ID). Set to 0 to
ignore.

finish_req_obj
The object, by object index, the user must have to successfully finish the quest. Set to 0 to ignore.

finish_req_objamount
The amount of the object defined in finish_req_obj the user must have to complete the quest.
Only used if finish_req_obj is > 0.

finish_req_killnpc
The index of the NPC that must be killed to complete the quest. Set to 0 to ignore.
finish_req_killnpcamount must be > 0 for this value to be used.

finish_req_killnpcamount
The amount of the NPC in finish_req_killnpc that must be killed. finish_req_killnpc must be > 0
for this value to be used.

finish_reward_exp
The amount of experience the user receives upon finishing the quest. Set to 0 for no experience
reward.

finish_reward_gold
The amount of gold the user receives upon finishing the quest. Set to 0 for no gold reward.

finish_reward_obj
The object the user receives upon finishing the quest. Set to 0 for no object reward.
finish_reward_objamount must be > 0 for this value to be used.

finish_reward_objamount
The amount of the reward object the user receives upon finishing a quest. finish_reward_obj must
be > 0 for this value to be used.

finish_reward_learnskill
The skill the user learns upon finishing the quest, as defined by the SkID (Skill ID).

Accounts
name
Player's account username

Return To Help Topics


Password
Player's password

user1 - user5
The user's 5 character names. Players can have up to 5 characters per account

friends
The player's friend list

Blocks
The player's ignore list

Property
MapNumber
Map Number of property

Owner
Username of player who owns property

Value
Property Value/Worth

ItemsInStore
Items in the owner's store (accessed through a servant NPC)

LastVisit
Date of Owner's Last Visit

Furniture
Furniture on Map

WarpX
X coordinate of where user warps to when teleporting to house

WarpY
Y coordinate of where user warps to when teleporting to house

Premium
Premium charge on items in store

AccessLvl
Access Level for map

Return To Help Topics


Update Server / Client
The updater does just like it says, it updates files. A common misconception is that it will do this fully
automatically for you, or that it will even update vbGORE itself. Well sorry to say, its neither of those,
but it is still very easy to use.
The updater has two components. Just like the game, these components are a server and a client. The
server holds the latest version of all the files and uploads it to the clients that request the download. The
files then are copied from the server to the client.

Adding Files
The first step to updating is to add files to be updated. All the update server (UpdateServer.exe) needs
to run is the exe itself along with the \UpdateFiles\ directory. In this directory, you will see a single
demo file if you have not changed anything that is basically a small read-me (in newer versions, it will
link you to this page). In this directory is where you want to put all the files you want updated.
Directory structure is read and preserved. The \UpdateFiles\ directory serves as the root directory of the
client. That means if you, for example, had MyFile.txt in \UpdateFiles\ directory directly, it will
download to the same directory the UpdateClient is in.
Server: \UpdateFiles\MyFile.txt
Client: \MyFile.txt

Server: \UpdateFiles\Grh\100.png
Client: \Grh\100.png

Server: \UpdateFiles\Data\NPCChat\english.txt
Client: \Data\NPCChat\english.txt

As you can see, you basically just want to copy over your copy of the client and all of its files into this
directory, then delete those that you do not want to keep up to date.

How It Works
When you run the server, you will notice a new folder pop up named \_Compressed\. What this folder
holds is a compressed version of a file, along with the MD5 hash of the original file, not the
compressed! This .md5 file is used for only one thing. When the server is run, instead of re-
compressing every single file, the MD5 hashes of the versions in the \_Compressed\ folder are
compared to the MD5 hashes of those in the \UpdateFiles\ folder. If the hash is the same, the file does
not need to be updated in the \_Compressed\ directory, which saves a lot of time. This allows you to
reboot the update server very quickly if it crashes, or only compress the files you change when you add
new ones.
The files in the \_Compressed\ folder are the actual ones that get sent to the client.

Compression
Two types of compression are used in the updater - LZMA and MAC. MAC, or Monkey Audio
Compression, is used on .wav format files while LZMA is used on every other file. The update server
and client will both just decide which one to use according to the file's suffix. If you have a graphic file

Return To Help Topics


and rename it to .wav, it will try to use MAC on it, but will fail and no compression will be made.
Likewise, if you have a .wav file and rename it to .bmp, it will use LZMA.
The compression is made at runtime on the update server and all of the compressed files are stored in
the \_Compressed\ directory. The files are only compressed if the MD5 hash in the \_Compressed\
directory is not equal to the MD5 hash of the same file in the \UpdateFiles\ directory, or the .MD5 file
can not be found.
The list of the server's files and information on those files, stored in the server as variable
ServerFileList(), is also compressed. More on this is explained in the next section.

Event Structure
The first thing to happen is the update server is loaded. During this time, the following events take
place:
• All the files in the \UpdateFiles\ are found and their path stored
• A list of "short file paths" (the path of the file the \UpdateFiles\ directory) is created
• A list of the size of all the files is created
• A MD5 hash for each file is created
• A string is created that gets stored in the array ServerFileList() which contains the
"short path", file size and MD5 hash (in that order) of every single file, and is then turned into a
byte array and compressed with LZMA
• A loop is made that checks if any of the files in \_Compressed\ are not equal to or missing those
in \UpdateFiles\ and makes the compressed version if needed
• The server opens up the socket and is ready for connections
Now the server has most all the important information it needs in RAM. The ServerFileList()
contains all the information it needs to send to the client disincluding the files themselves.
When a client connects to the server:
• Server recognizes the connection, accepts it and sends the ServerFileList() array
• Client decrypts the ServerFileList() array and compares the information in that to the
files it has - if any file is has different information or is missing, a request is made to the server
to download the file
• Server receives a file download request (given the "short file path") and sends the client the file
• Once the client finishes downloading the file, it decompresses it and deletes the compressed
version
• Once the client goes through every file and confirms them all being valid, it disconnects from
the server

Compression In vbGORE
Compression algorithms, along with times to use the compression, varies greatly from game to game.
Some games use compression on textures to reduce the RAM usage at a cost of CPU usage, while other
games use compression to reduce the size of easy-to-compress (ie redundant data) files to reduce disk
space usage. In vbGORE, the only default usage of compression is in the update server, so that is where
we will be concentrating our information.

Return To Help Topics


vbGORE uses compression in the update server for only one thing - less bandwidth usage. The cost of
doing this is that running the update server with new files requires them being compressed (old files are
preserved in compressed format and their integrity is checked with a MD5 hash to see if they have
changed) at runtime. Along with this, the client has to decompress the files. This means that even if you
don't mind running a compression on some files for 5 days straight on your powerful computer to get
the best compression, it isn't always a logical method. For example, PAQ8l, a compression method that
comes with vbGORE, creates the best compression by far out of all of the other compressions that
come with vbGORE, but the time it takes for compressing and decompressing files is pure insanity.

Compression Algorithms
The only compression algorithms we are going to be using in this article is the ones that come with
vbGORE. They are the following:
PAQ8l
PAQ8l is the March 8, 2007 edition of the PAQ compression series. It is one of the best
compression algorithms around, but also is easily the slowest and most memory intensive
compressions in this list. Only recommended for rare, special occasions.

LZMA
LZMA, or Lempel-Ziv-Markov chain-Algorithm, is an algorithm developed in 1998 and used in
7-Zip in the 7z format. It offers great compression at a decent speed. Its decompression is often a
few times faster than compression, though.

RLE
RLE, or Run-Length Encoding, is a very simple compression that takes runs of data (ie
AAAAAXAAA) and turns it into a shorter list (ie 5AX3A). This algorithm is very fast, though
slightly crippled from being implemented directly into the engine with VB.

RLE Looped
RLE Looped is the exact same as RLE, but the algorithm is run over and over until no more
compression can be achieved. The result is a slightly slower, yet very slightly better compression
than RLE.

Deflate64
Deflate64 is an enhanced version of Deflate, an algorithm that uses a combination of LZ77 and
Huffman encoding techniques to achieve compression. Although it has a very slow compression,
its decompression is very fast (can even reach over 100x faster than the compression). In result, it
makes a brilliant compression that is client-friendly.

Benchmarks
The following benchmarks are performed on an Intel T1300 1.66Ghz processor with 502MB of RAM
laptop. All encryption and decryption was done with the File Processor tool of vbGORE in compiled
mode.
The files compressed were all the files required by the client in the v0.5.2 release. This consisted of
231 files totaling at 15,473,310 bytes in size. Files were only compressed individually - no archiving.

Return To Help Topics


• Size is represented in percentage of original size, so 20% means that the compressed size is
OriginalSize * 0.2 bytes
• All times are presented in seconds
PAQ8l LZMA RLE RLE Looped Defate64
Size 56.4% 65.1% 97.8% 95.3% 71.0%
Compress time 2350.94 14.54 3.35 19.28 229.93
Decompress time 2253.39 5.02 0.98 2.88 3.82

Which To Use
Now that we know the benchmarks of the 5 algorithms, how do we decide which to use? First, we want
to take into consideration that compression time is not an important factor for the update server. It is
nice to have it compress fast, but I'm sure most people here wouldn't mind waiting an extra hour to gain
a bit more compression. The two important things to look at, then, is the size and decompression time.
Size has a heavier importance than decompression time, but PAQ8l is completely out until it can
manage compressing down to 5% of the original size. A full game distribution using PAQ8l is going to
run your decompression time into hours, if not days. If a client doesn't have over about 250MByes of
RAM to spare to the PAQ8l decompression process, you can expect the time to boost significantly
higher quickly.
RLE and RLE Looped are very fast, but their compression rate is way too weak, especially with RLE.
We'll hardly be saving any bandwidth with these two. That brings us down to the last two - LZMA and
Deflate64.
LZMA offers a better compression but at a slower decompression time. Though, 5.02 seconds to
decompress a series of so many files is hardly going to be a problem. For a full-sized game, this would
still take less than a few minutes for a complete update. The battle would be closer if Deflate64 had a
same compress time as LZMA, but the compression time is just insanely high compared to LZMA.
So in result, in my personal preference, the best algorithm to use for the update server would be
LZMA. If you really wanted to, PAQ8l can be used if you don't care that your users will have to suffer
a great downtime to extract the files. If you use PAQ8l, you better hope your updates are very small and
not frequent.

Publishing Your Game


At last you are ready to publish your game and compete with WoW! Well, maybe not WoW, but you
got a game that players want to play.

This section is dedicated to what you need to do when you want to release your game to make sure
everything is ready for others to use. Please note that these are just a few suggestions, and not
everything you should take into consideration. Make sure you always test your game extensively
before releasing it to the public.

Return To Help Topics


There are 3 MAJOR things you have to do. These are: 1: Change the IP in the client. 2: Set the server to
accept connections from all ips. 3: Pack up your client, and send it to other people. This guide explains
these in detail below. Make sure you read them in detail.
If you don't quite understand this article and would like another perspective on publishing a vbGORE
game, you might want to read this thread.

Client
The client must have the external IP of the computer the server is running on hardcoded into it. Your
external IP can be acquired through websites dedicated to showing you your external IP, such as
WhatsMyIP.org. To set the IP, do the following things:
Open GameClient.vbp using Visual Studio 6. NOTEPAD WILL NOT WORK. Open TCP.bas and
under Sub initSocket
Find:
SoxID = frmMain.GOREsock.Connect(GetIPFromHost("127.0.0.1"), 10200)

Change it to:
SoxID = frmMain.GOREsock.Connect(GetIPFromHost("YOUR-IP"), PORT)

You shouldn't need change the port unless you have a firewall or a application blocking it, so, let the
port stay as 10200. For the IP, just replace the "YOUR-IP" with the IP that appeared at WhatIsMyIp.org
Once you have changed this, make sure you compile a new server exe! (Unless you plan to run your
server from the IDE, which usually a good idea, this way you can debug crashes, etc.)

Server
The server needs your internal IP so it knows what IP to bind to internally in case of situations of
multiple computers per single IP address (such as being behind a router, which most households are).
Normally, you can just set the internal ip as 0.0.0.0.
The IP for the server is stored in ...\ServerData\Server.ini. In the case you are using one server (which
is true in most cases), scroll down to [SERVER1], find IP and change it to the IP you got from above.
If the server did not bind to 0.0.0.0, then try your internal IP. To get this value, go to Start, select "Run",
type in cmd, and press enter. You will see a black screen with some white / offwhite text. Enter the
word ipconfig into this and press enter, and you will be presented with your IP Address, Subnet Mask,
and Default Gateway.

Using A DNS
You can use a DNS (such as www.mygame.com or mygame.somesite.com) instead of a raw IP address.
This allows you to not have to update the client every time your IP address changes. If you do not
already have a DNS of your own, you can use No-IP.com to get one for free. This DNS will only be for
replacing your client IP, not your server IP! Instead of entering your IP in the client now, you enter in
your DNS. For example:

Return To Help Topics


SoxID = GOREsock.Connect(GetIPFromHost("127.0.0.1"), 10200)

Would become:
SoxID = GOREsock.Connect(GetIPFromHost("mygame.no-ip.com"), 10200)

You must make sure you update your DNS redirection IP every time your external IP changes, though.
This change can happen whenever your router reboots, so make sure to check after every time your
router shuts off.

Port Forwarding
If the server is on a computer behind a router, you will have to forward the ports used by the server in
your router. Also, if you have any firewall programs running on the server computer, you will have to
open the ports on those, too. More about port forwarding can be found at PortForward.com.

File Distribution
EditorMap
This is the remote program, that is used to edit all the maps related to your game.
EditorParticle
Helps you edit particle effects - requires you going through the code to edit the effects, though.
Used as a easier and faster way to view the effects. It's not really an editor.
GameClient
Runs the main game. You must have the server up to get past the login screen.
GameServer
Runs the main game server. The server will automatically initialize when loaded, so all you have
to do is open it up.
ToolColorCon
A simple program for converting between ARGB, RGB and Long values. This tool has been
intigrated into the Map Editor, which can be brought up by clicking the asterisk ( * ) next to color
input boxes.
ToolFreeNumber
Automatic finds for you the 15 smallest unused graphic file number and unused GRH value for
your convince.
ToolLogRemover
A tool that removes the current log files of the game.
ToolRebooter
When running, this tool automatically reboots the server if the GameServer crashes or stops
running for any reason.
ToolGrhCategorizer
This tool allows to sort all your GRH's graphics into different categorises for easier use in the
EditorMap.
ToolFolderCompress
An outdated/unused tool... compresses and decompresses a whole folder (use just as a reference).
ToolGrhDatMaker
Turns your Grh1.raw files into Grh.dat files, and calculates the values for your Grh.ini file.
ToolServerFPSViewer

Return To Help Topics


Allows to view the FPS, or speed, of your game server.
UpdateClient
The client for the auto-updater. This will download the files from the Update Server's update
directory only.
UpdateServer
Handles/sends files to the update client. Files must be placed into the UpdateFiles directory that
you wish to have updated. It will use the Last Edited date and file size of the client's files as a
reference on what needs to be updated.

Client Folders
These folders are needed by the client only:
Data
Holds general data of the game
Grh
Holds the graphic files
Music
Holds the game's music
Sfx
Holds the sound effect files

Server Folders
These folders are needed by the server only:
Backup
Contains backup map files from the server
Data2
Holds the server data
MapsEX
Holds more precise map information like object/npc placement, name, music info, etc.
ServerData
Holds general data for the server (such as MOTD)
UpdateFiles
Holds the files that will be sent to the client through the updater

Server And Client


These folders are needed by the server and client:
Visual Basic Libraries
Holds the DLLs and OCXs (only needed if not set up through installation program)
Maps
Holds the map display files

Return To Help Topics


Neither Client Nor Server
These folders are not required by the Client or Server
_Database Dump
The database batch file from the official release. Not required to run the database, and is not
needed after you batch upload to your database. Not required by anything (delete it, but always
make a backup of your database files)
3rd Party Tools
Tools for making the development of the server and server content easier. Made by members of
vbGORE, and is not officially supported by vbGORE. They are safe to use, though. Not required
by anything.
Icons
Holds the icon files. Only used to distribute the icons in *.ico format so you can add them to your
own forms. Not required by anything.
Code
Holds all the code files for every project. Unless you want your project open source, do not
distribute this, ever! Required for editing the code of any project.

To summarize; The client you distribute needs the following folders: Data, Grh, Music, Sfx, Maps It
will also need an EXE for your game (GameClient.exe by default - Make sure you have changed the IP
in this!) It's generally a good idea to include the config program, and if you have one set up, an updater
too. You will also need various DLLs, these can be found in a folder called "Libaries", either include
these along with the GameClient.exe or have the installer set them up. Make sure the
GoreSockClient.ocx is in there too.

Closing Remarks
Good luck on your game! Once you have a website up and going for your game, you can submit it to
vbGOREmania to posted to the Games Section.

Special thanks to Spodi who made vbGORE, on which vbGOREmania is based. Also thanks to the
vbGORE and vbGORE community for their contributions, especially those who contributed articles to
the vbGORE wiki, on which this guide is largely based.

Return To Help Topics

You might also like