Quake 4 Fortress Alpha
Contents |
Introduction
MOD: Quake 4 Fortress Alpha 001 Release Date: January 7, 2007 Readme Created: January 7, 2007 Last Update: January 7, 2007 by 3j
For the latest version of this readme, please visit http://www4.ncsu.edu/~cjcone/q4f/q4f_alpha_readme.html
Installation
Unzip the contents of q4f_alpha_001.zip to your main Quake 4 directory. Create a shortcut to your Quake4.exe with the parameters "+set fs_game q4f". I.E. "c:\quake4\Quake4.exe +set fs_game q4f". Now you should be able to run the shortcut to load Quake 4 Fortress.
Background
Quake 4 Fortress (Q4F) began development in August 2005 with some of the team members from the Doom 3 Fortress mod team. Development was going very well at first, especially leading up to the release of Quake 4 and the SDK. Unfortunately, Quake 4 did not deliver on its promise of having an engaging multiplayer expierience. Like most other multiplayer mods for the D3 engine, enthusiasm dwindled from the lack of a community for player input and developer support. The show pretty much came to an end in August of 2006 when the lead programmer had to stop development to focus on school and a new job.
The Alpha
The Q4F Alpha is now being released publicly, though its progress is nowhere near where we had hoped it would be when released. There are many reasons for releasing it now. The developers don't want all of their hard work to have been for nothing. As a public release, we hope that Q4F may be picked up by other interested developers to be brought closer to completion. Most of all, we hope that the Q4F Alpha source will be helpful to developers of other mods for Quake 4, and for future Fortress developers (whatever platform it may be).
The Team
Core
- Project Lead - Photeknix
- Lead Programmer - 3j (cjcone AT ncsu.edu)
- Level Designer(Bam) - Midori
- Level Designer(Bases) - Bolle
- Level Designer(Smooth) - TechX
- Models/Skins(Sentry,Players) - Hardman
Past Contributors
- Programming - Salteh
- Models(grenades) - Dconstruct
- Models(weapons) - Mesp
- Textures - CptTriscuit
- Level Designer(Mach) - nib
- Level Designer(Hardcore) - VilePickle
- Concept Artist - Recon
- Concept Artist - Tweed
- ??? - DukeHenry
Outsource
- Unlagged Code - TTK-Bandit (TTK-Bandit AT my-mail.ch)
Known Issues
The alpha is full of issues. The biggest is that it crashes. I think the longest playtest we had without any clients or the server crashing was two and a half map rotations. Few crashes would go straight to the desktop, none ever caused any harm to the machine. Still, play at your own risk :)
Besides that, there are far too many small polish bugs to mention here. Also, there are many Fortress-esque features (some class abilities) that were never fully implemented.
Just remember that this is an alpha that we are only releasing in hopes of being useful for the development community.
For Players
The Main Menu
When you run Q4F, the main menu should appear with the Q4F logo in the background and scrolling screenshots. The navigation starts with the 3 buttons located at the lower left of the screen. Here is the run-down of the different parts of the navigation:
-
Play - join/create Q4F servers
- Find Server: search for internet Q4F servers. The enhanced server browser allows you to both sort and filter for specific servers.
- Quick Connect: enter the IP address of the server you wish to connect to.
- Load Map: spawn a local server running the selected map.
-
Settings - adjustable game settings
- Player Info: personal player information and custom colors.
- Automation: toggle automatic execution of certain actions, such as executing class configs
- Effects: tweak what graphics and effects are played during the game
- View: adjust visual settings, such as your field of view and HUD options
- System: change core performance settings
- Audio: control audio properties including volumes, voice options, and grenade timer sounds
In the settings windows, hovering over an item will tell you what console variable it changes and a description of the variable
-
Config - key binds
- Movement: forward, right, left, etc...
- Attack/Actions: attacking (grenades,weapons), building, disguising, various TF actions
- Weapons: bind keys to specific weapons, or weapon slots
- Communication: chat, team chat, voice chat
The In-Game Menu
When you first connect to a server, you are presented with the In-Game menu. This menu can be accessed at any time during gameplay by pressing the 'Esc' key. The menu has 5 navigational tabs:
-
Teams
- Here you can select which team you want to play for. Each team lists how many players it has for each class type and the number of players currently playing as that class; so if you feel like sniping, don't join the team that is 2/2 for snipers (if the server has a limit set)
-
Classes
- After you select your team, you will be presented with this screen to select which class you wish to play as. Hovering over a class's name will provide you with a description and statistical analysis of the class at the bottom of your screen. The class details include the weapons and grenades the class is equipped with. Hover over the weapon or grenade names to view a description of those. Click on a class name to select that class. If the class is available, you will spawn and can begin play!
-
Stats
-
Everybody loves game stats. Q4F provides extensive player stats during the
game. The stats screen is divided into four areas:
-
Metric Selection: use the dropdown box to specify which stats you wish to see.
The options are:
- Weapon: view damage information for individual weapons. Many weapons have sub types of damages, such as direct or splash damage. Selecting the weapon itself and not one of the sub types will sum the total of its sub types
- Grenades: similar to weapons
- Teamplay: view stats for CTF-oriented gameplay
- General(default): overally kills, deaths, and damage
- Target Selection: use this dropdown to view the target of all the other metrics. I.E. selecting To/From team will display the damage you have given to/received from your team, rather than your enemies
- Measure: display the metrics as a total or as an average per minute
- Data Grid: displays rows of data for every player. The columns displayed depends on the metric selected
-
Metric Selection: use the dropdown box to specify which stats you wish to see.
The options are:
-
Everybody loves game stats. Q4F provides extensive player stats during the
game. The stats screen is divided into four areas:
- Chat select this tab to view the chat and death messages log.
- Main Menu clicking this tab will display the main menu. It does NOT disconnect you from the server.
Single Ambient Light
Like most other Q4 mods (and now baseq4), Q4F offers its own flavor of the single ambient light option to speed up rendering. Unlike most other mods, Q4F's ambient lighting actually uses a different post process effect that applies different shading to surfaces that are facing different directions. With this lighting turned on, the map looks more like as it would appear in the editor's simple lighting. We believe this type of lighting is much better than just the normal single ambient light because surfaces are easier to differentiate because they are shaded differently. Overall it less painful on the eyes than just the normal single ambient light fix. You can turn this option on through the settings in the main menu, or you can toggle the "q4f_ambientLighting" console variable.
Air Control / BunnyHopping
These two topics are before the most debated ones of the whole community. Huge amounts of time were put into trying to find an ideal solution for air control and bunny hopping settings that were fair to new people, kept the classes balanced, and that still kept the pace of the game high. Ultimately, all that work was scrapped and we ended up implemented QWTF style air control and bunny hopping (yes, even the acceleration). So to have good air control and accelerate while hopping around, just use the strafe keys in the direction that you are turning, while NOT holding forward. We hope that the pogostick jumping will make it easier for newbs.
WTF Happened to Reloading?
Reloading is technically still in the source code, but for right now the code always returns that the player's ammo ammount is his clip amount. I honestly can't even remember why reloading was taken out; it was either because it caused crashing, or it was taken out to speed up gameplay (probably both). Regardless, reloading isn't necessary now so fire away.
Chat Tokens
You can give information about yourself inside of chat messages using chat tokens. Q4F's chat tokens are:
- /L: your current location
- /D: the location of your last death
- /N: your name
- /C: your class name
- /H: your health amount
- /A: your armor amount
- /G: your disguise team and class
Key Aliases
Ever since QWTF, the ability for players to have keys that execute different commands when pressed vs. when released has been a necessity for Fortress players. Q4F offers that ability with the key alias system. The command to create such a binding is:
bindalias <key> <press commands>,<release commands>
For example, to bind z so that it primes the primary grenade on press and throws it on release:
bindalias z primeone,throwgren
Note: because of button limitations, you can only have 6 unique key bind aliases at one time
Custom Colors
Q4F allows players to specify custom team colors. Unlike other mods that pioneered custom team colors, Q4F's team colors affect every team-colored aspect of the game. This includes not only player models, but also the HUD and in game menu, sentry guns and dispensers, lights, emitters, and even level textures. To adjust your team colors, access the team colors selection area of the main menu (Main Menu->Settings->Player Info->Use Custom Colors). Q4F has three custom color options:
- Disabled use the standard red, blue, green, orange colors (or whatever the map specifies)
- Team vs Enemy selecting this option means that your team color and the enemy team color will always be the same, no matter what team you are on. So if you are on team 1 with your custom team color set to green, if you switch to team 2 your team color will remain green.
- Constant Team Color this option allows you to reassign colors to the teams. Normally team 1 is blue, but turning on this option allows you to make team 1 whatever color you like.
Custom Locations
A hail to the days of Qizmo, Q4F allows players to specify the names of locations throughout a map. Usage:
locationsAdd "team # or name" "location name" locationsRemove <location index> locationsList
locationsAdd will add the specified location right where you are standing in the map. Specifying the team name or # will make that team the owner of the location, so the location text properly reflects the team's name and color. For example:
locationsAdd "1" "Water Tunnel"
Creates a location belonging to team blue called the "Water Tunnel". This location's printed text will be "Blue Water Tunnel" with the word "Blue" being colored with team 1's team color.
"locationsList" lists all the map's locations, which can then be removed using "locationsRemove"
All map locations are stored in "<Q4F folder>/config/locations/<map_name>_locations.cfg", so they can always be tweaked manually in any text editor.
Custom Communications Menu
Communication is key in teamplay games. You can't be caught fumbling around trying to remember where you put that defensive bind to warn players of incoming enemies. Q4F tries to help this situation by providing players with a heirarchal custom communications menu. The menu can be opened in game using:
comMenu comMenu <category> comMenu <category> <item>
The main communications menu is just a list of sub categories, such as offensive, defense, etc... When you select a category, a list of items appears for the individual messages such as "Incoming Enemies!". The items display a chat message either to your team or to everyone, and an optional sound.
The entire layout is defined in "<Q4F folder>/config/comm/communcation.cfg". I suppose the best way to explain this file is with a commented example:
msgList offense { // 'offense' is the category identifier label "Offense" // label is the text to display for the category msgItem haveEnemyFlag { // 'haveEnemyFlag ' is the item identifier label "Have Enemy Flag" // label is the text to display for the item message "I HAVE the enemy flag!" // message is the chat message printed sound "" // sound is the name of the sound to play, as defined in def/q4f_pc_base.def target "team" // who to play the message to: "team" or "all" }
The category and item identifiers are useful for creating command shortcuts to the predefined menu items. So if I wanted to execute this menu item without having to trace through the menu, I could just execute the console command
comMenu offense haveEnemyFlag
Command/CVar Reference
Commands:
-
Movement:
- _forward, _back, _moveleft, _moveright, _moveup, _movedown
- Attack: _attack
- Zoom: _zoom
-
Change classes: changeclass <name> or changeclass <#>
- to change to medic, you can use changeclass medic or changeclass 5
- Prime primary grenade: primeone
- Prime secondary grenade: primetwo
- Throw primed grenade: throwgren
- Detonate pipebombs: detpipe
-
Drop ammunition: dropammo <ammo type> <amount to drop> <amount to
keep>
- Ammo types: shells, nails, rockets, cells
- to drop 50 shells while making sure to keep atleast 10: dropammo shells 50 10
- Build sentry or dispenser: build or build sentry, build dispenser
- Disguise team or class: disguise or disguise class <class name or #>', disguise team <team name or #>
Console variables:
- ui_pogostick: keep jumping just by holding jump
- q4f_sniperDotScale: scale of the sniper dot
- q4f_lightDetailLevel: scale what lights we display, based on volume
- q4f_ambientLighting: single ambient lighting
For Developers
Q4F was my first experience with C/C++ and gameplay programming, so let me apologize for the code from the start. Alot of the standalone code is in the Q4F folder, but there's also shittons spread throughout the entire SDK. If you have any questions, just email me (cjcone AT ncsu.edu) or AIM me (Vmpires Vngeance)
Key Aliases
-
Alias::Setalias_f( const idCmdArgs &args )
- this console command (linked as "bindalias") parses the key and commands from the user and sends the request to gameLocal.alias.CreateAlias(...)
-
Alias::CreateAlias( const char* key, idStr &pressCmds, idStr
&releaseCmds )
- finds an available BUTTON_* flag (for the user cmd)
- fills in the entry in the aliases array specifying the key (for re-assigning), the press command, and the release command
- immidiately issues the bind console command to bind this key to the newly created _button
-
In idPlayer::CommonUpdates (called from idPlayer::Think and
idPlayer::ClientPredictionThink)
- calls gameLocal.alias.UpdateAliases( Old Buttons, New Buttons )
-
Alias::UpdateAliases( short oldButtons, short newButtons )
- iterates through the aliasees array and checks for active aliases
- if the button wasn't pressed but is now, the press commands are sent to the cmd system
- otherwise if the button was pressed but isn't now, the release commands are sent to the cmd system
Custom Team Colors
- The color vectors are stored in "q4f_team*color" console variables
-
TFGame::Run()
- all the color variables are checked to see if they have been modified
- if so, it clears the modified flags for all and calls:
-
TFGame::UpdateTeamColors
- parses the team color console variables into the teamcolors vector array
-
iterates through all entities and issues the UpdateVisibleColor() command
- UpdateVisibleColor updates the entity's renderentity or renderlight RGB shader parms
-
updates the global shader parms, which teamcolored level textures reference
- there are conveniently 12 global shader parms, perfect for the RGB of 4 teams
-
calls UpdateHudTeamColor() on the local player
- sets the team_color_x, team_color_y, team_color_z GUI variables for all GUIs.
Scripted Game Types
Q4F tries to follow in the footsteps of its predecessors by giving level designers the ability to come up with new game types. Q4F facilitates this by using event-driven map scripts.
- There are two main entities used for creating game types: touchable entities and carryable entities
- Similar to Q3F, these entities can exist in various states such as invisible, disabled, active, and carried.
- When the entity is trying to change states, it calls the script delegate that is defined in its key-value pair properties
-
For example:
- Q4F's default CTF flags are defined in def/items.def
-
in the entity 'ctf_flag', it has the keys 'callOnActive', 'callOnIdle', and
'callOnCarry'
-
the values of these keys are script functions to call when the item is
REQUESTING to go into these states
- this is important: the return value of the delegate determines whether or not the item actually goes into the state
- if the script function returns true, the item enters that state; if false, the item does not change state
- When the flag is touched, the event 'callOnCarry' is called because the flag is a carryable item
- the flag's script delegate for that event is set to 'pickupCTFFlag' inside of "script/q4f_items.script"
- that script function is what does all the work of checking if the activator is the right team, etc...
- notice that it calls 'sys.setMapGuiInt()'. Maps can specify what GUI they want to overlay the player's screen with. Then they can use the setMapGUI* system calls to set state variables in the GUI that get replicated to clients. The flag icons that are drawn on the left hand side of your screen are controlled this way.
-
the values of these keys are script functions to call when the item is
REQUESTING to go into these states
- This entity scripting system is far from complete, but it has a lot of potential. Our entire Advanced CTF game type is defined in these scripts.
GUIMake
GUIMake requires the dotNet 1.1 framework to run.
I think D3/Q4's GUI system is cute in that it runs from scripts so that artisits and level designers can easily create their own simple GUI's, but the amount of copying and pasting you have to do for large GUI's such as the HUD or main menu is fucking ridiculous. I mean of all things to be object-oriented, the menu/HUD system should have been at the top of the list.
Since our HUD and menues were written from scratch, I thought it'd be nice to prototype things that appear often and are similar but that have only a few differences (buttons anyone???). So I quickly threw together a small program called GUIMake that let me do that. It pretty much just allows GUI source files to have preprocess directives similar to C, which can then be compiled into D3's GUI scripts.
There are several advantages to developing GUI's this way. For one, you can prototype repeated content without having to copy and paste the definitions everywhere. Then if you decide you want to change some aspect of that content, you don't have to scroll through thousands of lines of GUI script to change each individual instance, you can just adjust the prototype. And because you don't have to manage so many things at the same time, you can create much more powerful GUI's because you aren't afraid of having to adjust complex code all over the place. Finally, you can have parts of a single GUI split up into multiple files so you don't have one giant cluttered mess to sift through.
Now that I think about it, PERL probably would be the more ideal solution for this. But I didn't know PERL at the time, so I'll continue in case anyone prefers GUIMake.
GUIMake.exe is located in the "q4f/guis/" folder. Run it from the command line using
guimake <input file> <output file>
I.E.
guimake mainmenu.guim mainmenu.gui
I just chose to make my GUI source files .guim, any ascii text will do.
There are only a few directives that GUIMake knows about. Keep in mind that when I made this I didn't really intend it for public use. If something is syntactically wrong, it *should* toss an error to the command prompt, but I make no promises
The directives:
- #import <file>: Reads the specified local file directly into where the #import directive is, before all other directives are processed
-
#define <FuncName>( <Param1>, <Param2>, ... <ParamN> )
... <#end>: creates a prototype, very similar to the C "#define"
directive.
- Once a prototype is defined, it can be used by treating its FuncName as a directive with parameters. The arguments you pass in to the function call will just string-replace all instances of the Params that occur within the defines prototype text. For example:
#define SimpleButton( %x%, %y%, %text% ) windowDef simpleButton_%x%_%y% { rect %x%, %y%, 50, 25 visible 1 text "%text%" } #end #SimpleButton( 50, 75, My Text )
-
- When processed will produce the text:
windowDef simpleButton_50_75 { rect 50, 75, 50, 25 visible 1 text "My Text" }
- Notice that quotes aren't required when passing in parameters. The compiler just reads in all the characters between the paranetheses and commads, and trims the leading and trailing white space. However, if you want leading or trailing white space, you can delimit your arguments using single or double quotes, such as:
#SimpleButton( 50, 75, " My Text " )
- If you wish to include either single or double quotes as part of your text, use the other as a delimiter, such as:
#SimpleButton( 50, 75, "' My Text '" ) #SimpleButton( 50, 75, '" My Text "' )
- You can skip parameters or not fill in all the parameters; left-over or empty arguments are just replaced with blank text
That's pretty much it as far as GUIMake goes. It is much faster at producing the final text than at parsing files, so it can get pretty slow when parsing large files that don't have many directives.
I've included all the source .guim files for our main menu and HUD so there are plenty of examples if you're interested
Everything Else
I'll put more info up at people's request...