Compare commits

...

102 commits

Author SHA1 Message Date
f4ca03ba02 func_tracktrain: when moving vertically exclusively, do not change the angle. 2025-02-24 19:03:37 -08:00
d3a18d5485 Menu-FN: fix preview aspect ratio to be 4:3 2025-02-24 17:22:26 -08:00
5e5b850ec1 vguiButton: Change behaviour under which a button acts as disabled.
vguiWidget: add generic Enable, Disable accessor methods.
2025-02-24 17:22:07 -08:00
b82d068065 func_door/func_door_rotating: Fixes to behaviour when Blocked. 2025-02-24 17:20:43 -08:00
9fd8b6d218 ncWeapon: some sanity checks and slightly saner networking order. 2025-02-24 17:19:36 -08:00
2215a256fe game_text: fix Input() recursion 2025-02-23 06:19:25 -08:00
b01c7bc925 base/quake.rc: set mintic and plug_load ode 2025-02-23 06:19:13 -08:00
e504a27aea trigger_endround: initial implementation 2025-02-23 06:18:59 -08:00
c6042c73f0 fade.qc: convert the maxalpha after receiving it, since we changed the way colors are sent. 2025-02-23 06:18:06 -08:00
267d9ea785 env_hudcounter: initial implementation 2025-02-23 06:17:05 -08:00
bdd7073016 ncItem: don't Destroy() when CreatedByMap() returns true 2025-02-23 06:16:15 -08:00
111d6923bf isPlayer: classname sanity check. 2025-02-23 06:15:49 -08:00
7bfe67c3b5 ncRenderableEntity: handle RFX_GLOWSHELL's additive effect solely in material 2025-02-22 02:09:52 -08:00
3114c1cef1 remove src/xr/include.src 2025-02-22 02:08:45 -08:00
21bdfc7769 Draft: improved item networking on owner 2025-02-12 16:44:00 -08:00
07d230983f ncRenderableEntity: network optimisation for brush based entities 2025-02-12 01:52:02 -08:00
af5b552cfc server: slightly more reliably signaling for when precaches are allowed. 2025-02-12 01:51:28 -08:00
5e860ea53b Tools/make_dist.sh: no longer require 'tree' 2025-02-11 02:25:07 -08:00
f4238fdd2f Makefile fteqcc: mkdir ThirdParty if it doesn't exist 2025-02-11 02:17:19 -08:00
b470c548fe Makefile: dist-pak needs fteqcc 2025-02-11 01:44:06 -08:00
7bd9ea1486 EntityDef: saner precache timeframe check. 2025-02-09 01:35:07 -08:00
143e247cf3 ncItem: unset m_nextItem and owner fields in OnRemoveEntity, exit out of PreFrame when freed 2025-02-09 01:17:16 -08:00
e60556e124 RuleC: dedicated precache callback which will be called at a specific time. 2025-02-09 01:16:39 -08:00
3e421aab57 Fix a slew of warnings. 2025-02-08 22:19:53 -08:00
71dc508bad ncWeapon: unstick viewzoom 2025-02-07 22:40:00 -08:00
0d86ba22e9 ncWeapon: move AnimEvent 5000 into ncRenderableEntity, allow fireinfo to control those for the viewmodel in ncWeapon fireInfos 2025-02-07 22:15:11 -08:00
475000a1b8 ncWeapon: streamline muzzleflash assignment and make it fireInfo oriented. 2025-02-07 20:54:28 -08:00
d0e90cd07b ncItem/ncPhysicsEntity: slight networking tweaks (networking with lots of physics props should be less taxing) 2025-02-03 17:22:31 -08:00
b9d7e0794e Menu-VGUI: Quick and dirty server list. 2025-02-03 16:23:33 -08:00
d15a8d3333 GameLibrary: adjusted support for scanning mod packages for new packaging standard 2025-02-02 23:02:30 -08:00
85488eeccf unbreak against latest fteqcc 2025-01-31 23:58:54 -08:00
19b47e393c func_tracktrain: unbreak.
more cleanups.
2025-01-14 03:00:12 -08:00
6867396b09 Move navigational helper functions into ncNavInfo 2025-01-13 17:03:40 -08:00
fd90be879c Rename a bunch of old names. 2025-01-13 14:29:09 -08:00
8503cad633 Initial merge of the new NPC schedule/task system. 2025-01-13 13:36:48 -08:00
ee8428d8b5 add some progs 2025-01-08 22:59:04 -08:00
31ed19cb47 env_muzzleflash: add a hack to force additive rendering (HL1...) 2025-01-03 04:12:24 -08:00
ba6f788ab8 Server StartFrame: externset frametime for ruleC/mapC because that won't happen itself through the engine? 2025-01-03 01:56:25 -08:00
dffc9dc832 ncProjectile: added callback method HasExploded(void) 2025-01-03 01:55:36 -08:00
ca316277e7 NSEntity: remove parenting hack, do our own parenting as the engine won't do it for entities using .SendEntity (virtually every single one in Nuclide) 2025-01-03 01:55:03 -08:00
5cf55b8271 Server: load singleplayer.dat or deathmatch.dat when appropriate in RuleC_Init 2025-01-02 19:24:48 -08:00
d41b90c081 Base: Give some love to base/
VGUI-Menu: friendList, chat backend, textview class proto
SurfaceProps: Flesh impacts recognition
PropData: BreakModels now use a bodyque to limit possible physics overhead
PMove: falldamage, liquids can now be configured via external decl
NSWeapon: added alternative punchangle based on springs, 'punchSpring X Y Z' in decl
API: Team class management APIS
NSPhysicsEntity: Optimised, optimised, optimised. New cvar: phys_lowspec. Scraping, impact effects etc have been added.
More polish everywhere else
2025-01-02 18:53:55 -08:00
2db52608b1 Server: streamline gamerule progs interface 2024-11-05 20:36:15 -08:00
967ac0145b Client: add init() 2024-11-04 01:13:04 -08:00
5c6f405872 Client: add vv_flag VFL_VIDREMOVE, for client-side entities needing deletion on renderer restart. 2024-11-04 01:12:09 -08:00
70d6302808 Server: new command: listMapTweaks 2024-11-02 02:56:33 -07:00
26f81235c8 NSAttack: add 'drop' key 2024-11-02 02:53:18 -07:00
9d4bd4d90c NSTrigger: add explicit "UseTargets" input to be used by model events and stuff. 2024-11-01 03:59:12 -07:00
0d6d881437 NSRenderableEntity: RM_ADDITIVE ignores rendercolor 0 0 0 it appears. (zpo_contingency) 2024-11-01 03:58:25 -07:00
dcb17255a3 func_ladder: duplicate self to act as a collision entity you cannot pass through, won't fight CONTENT_LADDER 2024-11-01 03:03:20 -07:00
aa4b96f68c NSRagdoll: some minor optimisations.
Platform: Background handler will look for assets in current game-dir for prioritisation
Server: add server command `setLightStyle` (two args, style num + pattern)
Bunch more tiny fixes for various classes.
2024-10-31 04:11:30 -07:00
b891015423 NSGameRules:: add NPCDeath callback method. 2024-10-31 04:00:23 -07:00
a8e4893f2a env_beam: add additional Inputs and keys to make them useful for monsters 2024-10-31 03:58:12 -07:00
b8b0ddcb1b Makefile: don't remove fteqw binaries when cleaning game binaries. 2024-10-31 03:55:45 -07:00
45b2f300f8 Menu-VGUI: Title support. 2024-10-18 02:40:35 -07:00
af708c1e90 Makefile: add vacuum target.
Util_ChangeExtension: will handle a sensible fallback case now
NSItem: query MaxHealth, MaxArmor properly.
2024-10-17 02:15:35 -07:00
81d61ac3da multiprogs additions, decl integration, more of everything really 2024-10-16 22:52:27 -07:00
e27e2a85ec
* fix dirFromTarget() logic
* passing of extra damageDecl values from radiusDamage() calls

* add fun cg_modelSpin/Bob cvars

* NSActor::MaxAmmo(int) added

* NSItem::ItemPickUpCheck(entity) added

* base/ cleanup
2024-09-20 09:38:02 -07:00
0909b91703 last weeks work, read plan 2024-09-17 12:46:31 -07:00
a7edfdf5d0 NSSurfacePropEntity: load surfacedata from propdata when not set 2024-09-09 22:05:09 -07:00
9b1b536363 SurfaceProp: load _manifest.txt file (optional) 2024-09-09 22:04:09 -07:00
b0548e6390
Menu-VGUI: fix modelviewer background path. 2024-09-06 09:27:46 -07:00
74bc920c60
unpackStringCommand: support "cvar:[cvar_name]" query syntax 2024-09-06 09:27:03 -07:00
9bb8dcab7c
PropData: load more property values from Source Engine binary model format. 2024-09-06 09:26:36 -07:00
a82c978026
SurfaceProp: load Source Engine _manifest file. 2024-09-06 09:25:43 -07:00
ab755faaf5
Makefile: read required plugins from file, build alongside dist-engine target, compile shader tools 2024-09-06 09:25:01 -07:00
bf567da9ba
* spawn/speed optimisation for NSPhysicsEntity
* pick a better dmgDir for hitscan NSProjectiles so physics ent feedback is accurate

* fix NSPhysicsEntities not becoming invulnerable after breaking
2024-09-03 12:15:16 -07:00
b60d420692 Push all the latest commits from this week's worklog, changes for RT2 2024-09-01 23:57:51 -07:00
8ab066ffe1
NSProjectile: allow projectiles without models to still have trails etc. 2024-08-14 18:09:18 -07:00
02301994ce
- add GetNextWeapon(), GetPreviousWeapon(), GetLastWeapon() to NSActor
- allow weapon sorting in overridable NSActor::SortWeaponChain() method
- add isClient() as isPlayer() doesn't take spectators into account
- fix various CS specific zone
- ungodly amount of documentation improvements
- worldspawn ent work delegated to separate ent slot
- NSClientPlayer::MakePlayer no longer wipes the inventory.
- fix team selection race condition exploit in FreeCS
2024-08-14 16:10:57 -07:00
e4ab1bd671
document 'Physics' group, related to external-simulator physics
def > decls/def
sound/*.sndshd > decls/sound/*.sndshd
efx/ > decls/efx
NSWeapon: add "snd_fireStart", "snd_fireStop", "snd_fireLoop"
NSWeapon: add "view_geomset" to FireInfo
NSWeapon: add "knockbackRelease" to FireInfo
NSWeapon: add "altMode" toggle
NSWeapon: "actLoop" decoupled from "actFireStart"
NSWeapon: fireRate inherited from model if not set
NSWeapon: query all sequences from FireInfo
NSWeapon privatize weapon state
solidify more def documentation across the board
NSWeapon add "chargeTime" key
rework state machine in NSWeapon
reload timing separation in NSWeapon
add overheatLength, overheatPerShot to NSWeapon
2024-08-11 13:39:51 -07:00
21b68d1938
NSWeapon: - add "chargeTime" key
rework state machine in NSWeapon
reload timing separation in NSWeapon
2024-08-05 18:06:18 -07:00
c3f527d5e5
NSActor: add SwitchToBestWeapon(bool ignoreCurrent) 2024-07-31 17:28:35 -07:00
0adf97e2de
NSWeapon: reloadTime also needs to affect shotgun reloads. 2024-07-31 00:43:02 -07:00
792c764c2e
NSWeapon: add 'reloadTime' key override 2024-07-31 00:21:09 -07:00
7c68a0317e
NSWeapon: add method WeaponIsFiring() 2024-07-30 20:45:04 -07:00
caac73bec9
NSProjectile: don't spawn debris on monsters.
NSIO: change EntWarning to EntLog for unknown spawn data keys.
2024-07-30 20:20:07 -07:00
4a636693bc
NSClientPlayer::Physics_Fall: fix falldamage 2024-07-30 20:16:05 -07:00
37f5c907b4
NSWeapon: rename some methods to be more verbose, add WeaponStartedFiring(), WeaponStoppedFiring()
NSDict: add InitWithSpawnData(string)
2024-07-30 20:15:43 -07:00
4315e92ef5
Client/Server: unset input_cursor_entitynumber because the engine wouldn't 2024-07-30 14:43:03 -07:00
c27ab5dd5a
NSItem: play pickup noise on player instead of self 2024-07-26 14:51:30 -07:00
d936e57aa5
Rename NSNavAI to NSActor. 2024-07-26 14:32:49 -07:00
935c0fd543
NSItem: handle health/armor/ammo drops outside Touch.
New cmds: giveInventoryItem, removeInventoryItem, removeAllInventoryItems
2024-07-26 12:53:57 -07:00
760bc4a8fa
NSWeapon: fix punchangle, add cvar g_infiniteAmmo 2024-07-26 11:44:51 -07:00
52af82b985
NSProjectile: made hitscans overridable
NSWeapon: Allow override of Weapon Fire/Release events with FiredWeapon(fireInfo), ReleasedWeapon(string)
2024-07-24 18:50:46 -07:00
ff1681901f
Update .gitignore with comments (thanks Xylemon) 2024-07-24 17:38:51 -07:00
1282bc42dd
NSNavAI: add methods GetCurrentWeapon(), SwitchToWeapon(string), SwitchToExactWeapon(NSWeapon) 2024-07-24 14:26:20 -07:00
24a9ef71ac
NSWeapon: add "speed_mod" key for manipulating the player speed. 2024-07-24 14:25:41 -07:00
5bb9fbf3af
NSMonster: only respect "sequence" on monsters when they're flagged as dead. 2024-07-24 10:10:53 -07:00
c829d0453e
Fixes in base/, move hud weapon selection references out 2024-07-23 18:08:33 -07:00
f9dd7362b4
NSSurfacePropEntity: change string damageDef to NSDict damageDecl in Damage() 2024-07-18 16:32:05 -07:00
8b4b7f0a26
Reserve the id keyword, fix some struct members to comply 2024-07-18 13:44:52 -07:00
ac037bb887
Use NSDict instead of sprintfing strings and sending them over Damage() 2024-07-18 13:33:36 -07:00
e9145091fd
Clear warnings. 2024-07-18 13:04:42 -07:00
965d9e96d6
NSEntity: add SetOriginUnstick(), SetBotTag()
NSWeapon: basic inventory management functions
2024-07-17 14:21:44 -07:00
a852f887e2
More fixes. 2024-07-11 15:24:33 -07:00
8ace54224c
The mother of experimental commits. 2024-06-22 00:24:13 -07:00
bab74ba6fd
Change the inheritance graph of NSBot, NSClient etc. 2024-04-22 22:47:54 -07:00
bd7e78ab94
NSNavAI: Inventory management functions. 2024-04-22 21:47:02 -07:00
822a7221b2
WIP pmove, AI, etc. changes 2024-04-22 15:11:12 -07:00
d5053299dc
func_rot_button: Fix spawnflag 32. Mistakenly thought to be 'toggle'. 2024-03-26 16:14:07 -07:00
53bab46f7d
func_button: if "lip" isn't set, set it to be 4. 2024-03-26 12:45:38 -07:00
4387 changed files with 537242 additions and 78327 deletions

BIN
.dir.tiff

Binary file not shown.

139
.gitignore vendored
View file

@ -1,48 +1,103 @@
*~
# Nuclide
Documentation/html/
darkstar/
noffice/
pvk/
ship/
src/client/cstrike.new
src/server/cstrike.new
src/shared/cstrike.new
src/client/hl2
src/server/hl2
src/shared/hl2
src/client/wastes
src/server/wastes
src/shared/wastes
*.lno
maptimes.txt
iplog.txt
entities.def
*.pk3
*.dat
*.way
*.lvc
*.fsv
*.pak
*.pk3
*.pk4
*.kdev4
csqccore.txt
*.log
ssqccore.txt
menucore.txt
conhistory.txt
ThirdParty/
# Tools
fteqcc
fteqw
imgtool
vmap
vvmtool
# FTEQW / idTech engine files
condump.txt
config.cfg
conhistory.txt
csqccore.txt
entities.def
fte.cfg
nuclide.cfg
qkey
fullchain.pem
installed.lst
*.kdev4
hl2/*
bshift/*
baseq2/*
gangstawars/*
nightfire/*
iplog.txt
maptimes.txt
menucore.txt
nuclide.cfg
privkey.pem
qkey
ssqccore.txt
# Development and Data files
*~
*.dat
*.fsv
*.ico
src/engine/
bin/
*.kdev4
*.kdev4
*.lno
*.log
*.lvc
*.pak
*.pk3
*.pk3
*.pk4
*.way
# Binary files
*_x86*
*_x64*
*.dll
# Known Games and Mods
#
# Ideally you would add
# your project here as well
action/
AbsoluteZero/
base_pbr/
baseq2/
baseq3/
bshift/
cod/
cod4/
css/
cstrike/
czero/
czeror/
darkstar/
dmc/
dods/
fortress/
gangstawars/
gearbox/
gmod9/
hhdeath/
hl2/
hl2mp/
hunger/
id1/
left4dead/
nightfire/
noffice/
overturn/
poke646/
portal/
pvk/
ranon/
rewolf/
scihunt/
ship/
tf/
tf2/
tfc/
dk/
basedk/
mainkp/
ts/
valve/
wastes/
zp/

15
COPYING Normal file
View file

@ -0,0 +1,15 @@
ISC License
Copyright (c) 2016-2024 Vera Visions L.L.C.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

111
Documentation/About.md Normal file
View file

@ -0,0 +1,111 @@
# About {#about}
The Nuclide project produces a freely available game-logic component and
development platform on top of [FTE](https://www.fteqw.org); which is a featureful engine based on the **1999** source code release of **Quake** (1996) by id Software.
![](wand.png) **The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.**
It is targeted towards developers with a background/interest in id Technology, and we incorporate design aspects from across the known spectrum of existing engines and tech.
It comes with a simple example game (simply referred to as 'TestGame' or 'Base') and some test maps. There's also some other, third-party example projects.
# Features
## Rendering System
The rendering system in FTE allows for a wide range of styles for low system requirements, due to a versatile renderer supporting Vulkan, OpenGL (with and without shaders) to legacy versions of Direct3D on Windows.
- **Physically Based Rendering.** State-of-the-art basis for rendering is standard and in base.
- **Lighting system choice.** You're not forced to use lightmapped-only paths. All entities are prepared to be mixed with different lighting technologies seamlessly.
- **Iris-adaptation, like Source HDR.** Simulated feel of high-dynamic-range with iris adaption can be turned on/off for every game. Of course we also have real HDR support in-engine.
## Modeling & Animation
With the wide selection of formats that FTE supports, rest assured your content gets in the game real easy.
The SDK itself is prepared to work with most formats.*
- **Hitmeshes..** Artists can use geometry in their ref to define precise damage areas, which any hitscan accurately detects.
- **Model events.** Define animation-sequence events that should happen on an exact keyframe basis, to be interpreted by both client and server.
- **Activities.** No longer hard-code which sequences and behaviour a model can express. The model can communicate it itself.
*Formats other than VVM require the use of an external, plain text file to define framegroups, events and activities.
## Environments
Make levels with the tools you've used before, and have been maintained by the community for decades.
- **Integrated Radiant.** Generate game-packs for your game with a single command, and get mapping right away.
- **Powerful BSP compiler.** Use *VMAP* to bake levels like you're used to from similar engine technology, with high quality lightmaps, cubemap-based environment mapping and adjustable vertex colors on spline-based meshes.
- **Map-specific rules.** Let the level control some aspects of the simulation through the use of an external [QuakeC progs](@ref progs).
## Physics
Nuclide integrates [Open Dynamics Engine](http://www.ode.org) to achieve networked, physically simulated bodies and ragdolls with consistent, game-specific feedback.
- **Consistent Prop Behaviour.** Set up a model once with its [mass and other prop data](@ref propdata) and Nuclide will handle impacts against other entities and real-world interactions.
- **Advanced constraint systems.** Set up rigs of constraints, like welds, ropes, pulleys and sliding mechanisms.
## Game Mechanics
- **IO System.** A custom implementation of a *Source Engine* compatible input output system for entities. Utilized by AI tasks/schedules as well.
- **Navmesh navigation.** Solid pathfinding within complex environments, with a simple-to-use navmesh editor.
- **Configurable movement.** Players, NPCs and bots can walk, run, sprint, duck, prone around the levels.
## Programming
Complete engine access available in the form of C code.
When writing game-logic, you'll be writing primarily in QuakeC, which is greatly enhanced by [FTEQCC](https://www.fteqcc.org).
However, that is not the only way you can modify aspects of the game greatly.
- **Higher-level prototyping.** Defining game objects such as NPCs, items and behaviour can be done entirely using external [decl](@ref decl) files.
- **Powerful debugging.** Complementing FTE's console and debugging capabilities is detailed event-logging with a focus on data and entity IDs for easy identification.
- **Easy custom builds.** Creating custom branded builds is as easy as copying a header file and editing it.
- **Easy deployment.** Build Steam depot folders with 1 command, building game archives and cross-platform binaries using gcc and mingw64 on Linux.
## Audio
The engine provides backends for audio through OpenAL, which has its DSP/Reverb features integrated into our SDK.
- **Sound scripting.** Customize the sound of any surface, and fine-tune how each sound is perceived from near and far using plain text definitions.
- **Voice chat integration..** Additional features such as player voice-chat (using Opus or Speex codecs) over the protocol are integrated.
- **Real-time sound file stitching.** Play a series of separate sounds as if they were one, with adjustable pitch and volume between segments.
## Networking
Tried and tested networking powered by QuakeWorld isn't the only thing it has got going for it.
- **Rock-solid lag compensation.** The player movement, including weapon and vehicle handling is predicted (simulated on both client and server) for smooth, lag-free feeling gameplay.
- **Integrated messaging.**. Players can keep track of their friends using a persistent chat/friends-list system.
- **Workshop style package manager.** Players can download levels, skins and addons through the built-in addon manager.
- **Hassle-free server hosting.** Players can host servers without the need for port forwarding using **Frag-Net**.
# Frequently Asked Questions
## 1. Why might I want to use it? {#why}
![](cross.png) You might be migrating from an engine that is no longer being licensed and don't want to learn a new engine and toolchain.
![](bricks.png) You might want to develop a game using a lot of complex and well-tested objects
which might be tedious to implement on your own.
![](wrench.png) You might want to run or make modifications for a game using Nuclide and need full
control over what you can do.
## 2. How free is Nuclide? {#license}
Everything in Nuclide is **free software**. The copyright terms for the game-logic are
very permitting. Nuclide *does not use the GPL* as a point of reference in terms of license, it instead uses a **ISC-like license**. This means you can use, copy, modify and distribute the code and work resulting from it for any purpose.
@note Please read the very short 'LICENSE' document for details.
## 3. What are the alternatives? {#alternatives}
Implementing systems such as prediction, complex map objects and entities on
your own, from scratch - or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**.
## 4. Any example projects? {#examples}
- [The Wastes](https://store.steampowered.com/app/793670) is a commerical game built using Nuclide.
- [Rad-Therapy](https://www.github.com/eukara/freehl) is a clone of 'Half-Life: Deathmatch' on Nuclide.
- [Tactical-Retreat](https://www.github.com/eukara/freecs) is a clone of 'Counter-Strike', for Rad-Therapy.

15
Documentation/Bots.md Normal file
View file

@ -0,0 +1,15 @@
# Bots {#bots}
![](computer.png) Bots are CPU controlled opponents. They can be useful for development, debugging but can also fun to play with.
They're 'fake' client entities, traversing the level, and acting upon objectives they either figure out themselves, or are told to to act a certain way.
*We encourage any multiplayer game to support them*, because they often also fill in the function of balancing teams. There's a whole slew of benefits of supporting bots, and *players will generally thank you for including them*.
## Technical Info
Bots are handled by BotLib, located under `src/botlib/` in the source tree.
Nuclide's BotLib takes some inspiration from **Quake III Arena** its bots, but shares no code or specific ideas or implementations. We do not use **AAS** for navigation, we leverage the route/pathfinding system **FTEQW** provides. Bots also share some code with regular NPC/Monster type entities through the use of the ncActor class.
@note Games are allowed to handle how they want to integrate bots themselves, but for development purposes there are ways to force bots to spawn also.

View file

@ -1,55 +0,0 @@
# Bots
Bots are handled by BotLib, located under `src/botlib` in the directory tree.
Nuclide's BotLib takes some inspiration from **Quake III Arena** its bots, but shares no code or specific ideas or implementations. We do not use **AAS** for navigation, we leverage the route/pathfinding system **FTEQW** provides. Bots also share some code with regular NPC/Monster type entities through the use of the NSNavAI class.
Games are allowed to handle how they want to integrate bots themselves, but for development purposes there are ways to force bots to spawn.
# Bot profiles
Nuclide has support for bot profiles, like in **Quake III Arena**. They work differently although they appear compatible by design. You can define them in a script that looks something like this and is located at `scripts/bots.txt` in your game directory:
```
{
name Albert
model zombie01
topcolor 0xeff
bottomcolor 0xff0020
}
{
name Susie
model police02
topcolor 0xff6b00
bottomcolor 0xff0b00
}
{
name Dog
funname ^4D^2o^1g
model dog01
topcolor 0x9200ff
bottomcolor 0xc800ff
}
```
Only the `name` key is required. The only other special key is `funname` which sets the nickname to be different from the internal name. The other keys are set as user info (setinfo) keys on the bot client.
This will allow games to add whatever extra keys they wish that they can then recognize anywhere in the client/server codebase. No additional networking or APIs necessary. Simply query bot properties via their userinfo.
# Bot Console Commands
## addBot [profile name]
Adds a bot to the current game.
## killAllBots
Force kills and respawns bots in the current game.
## resetAllBotsGoals
Force reset bots current trajectory and goals.
# Bot Console Variables
See `platform/cvars.cfg` under the `// bots` section.

View file

@ -0,0 +1,53 @@
# Bots {#bots}
## Console Commands {#bot_commands}
### addBot [profile name]
Adds a bot to the current game.
### killAllBots
Force kills and respawns bots in the current game.
### resetAllBotsGoals
Force reset bots current trajectory and goals.
## Bot Console Variables
### bot_enable
Enable (1) or disable (0) usage of bots in the game. Default is 1.
### bot_pause
Enable (1) or disable (0) an interrupt for the Bot AIs thinking. Default is 0.
### bot_noChat
Enable (1) or disable (0) a suppression of any bot chatter. Default is 0.
### bot_fastChat
Enable (1) or disable (0) bot chatter that does not stop other inputs. Default is 0.
### bot_debug
Enable (1) or disable (0) bot debug features that otherwise won't work. Default is 0.
### bot_developer
Enable (1) or disable (0) bot debug text in console. Default is 0.
### bot_minClients
When set, ensures to fill the server with this many players/bots. Default is -1.
### bot_aimless
Enable (1) or disable (0) bot not knowing where to go. Will keep generating a new place to walk to.
### bot_crouch
Enable (1) or disable (0) the forcing of bots crouching down.
### bot_walk
Enable (1) or disable (0) the restriction of bots to walking speed.
### bot_prone
Enable (1) or disable (0) the forcing of bots to crawl/prone.
### bot_dont_shoot
Enable (1) or disable (0) bot pacifist mode.

View file

@ -0,0 +1,31 @@
# Bots {#bots}
## Profiles {#bot_profiles}
Nuclide has support for bot profiles, like in **Quake III Arena**. They work differently although they appear compatible by design. You can define them in a script that looks something like this and is located at `scripts/bots.txt` in your game directory:
```
{
name Albert
model zombie01
topcolor 0xeff
bottomcolor 0xff0020
}
{
name Susie
model police02
topcolor 0xff6b00
bottomcolor 0xff0b00
}
{
name Dog
funname ^4D^2o^1g
model dog01
topcolor 0x9200ff
bottomcolor 0xc800ff
}
```
Only the `name` key is required. The only other special key is `funname` which sets the nickname to be different from the internal name. The other keys are set as user info (setinfo) keys on the bot client.
This will allow games to add whatever extra keys they wish that they can then recognize anywhere in the client/server codebase. No additional networking or APIs necessary. Simply query bot properties via their userinfo.

View file

@ -0,0 +1,34 @@
# Bots {#bots}
## Bot Waypoints {#bot_waypoints}
Bots will read from the same navmesh as the rest of the artificial intelligence.
You can edit the navmesh using the `way_menu` command.
![Nuclide's way_menu Interface](nuclide-way.png)
You can then use the `slot` keys (usually bound to numbers **1** - **9** including **0**) to navigate the menu.
### Nodes
Nodes make up the smallest part of the navmesh, but they define all the paths that are walkable.
### Links
Links are connections between nodes. You can have as many links between nodes as you wish.
Those connections being made can also have special **flags**.
![Flags available on links](nuclide-way-flags.png)
The **Jump** flag will ensure that the bot will jump when it hits **point A**, before arriving at **point B**. You want to ensure those nodes are close to the edge of a gap for example.
The **Crouch** flag will force the bot to crouch while traversing **point A** to **point B**.
The **Walk** flag will force the bot to walk while traversing **point A** to **point B**.
The **Aim** flag will force the bot to forcefully look at the next node directly while traversing **point A** to **point B**. This is useful to control where they're looking at in order to make [ladders](@ref func_ladder) climbable by them.
The **Use** flag will trigger the bot into simulating a **use** action (simular to `+use`) to the nearest usable object in proximity of **point A**.
The **Hazardous** flag will mark a path between two points as dangerous, and thus will be avoided by bots at specific times.

View file

@ -1,268 +1,110 @@
# Building
# Building {#building}
## Preface
If you don't plan on modifying the engine, then you probably shouldn't! You can grab binaries from [FTEQW](https://www.fteqw.org) and move them into the Nuclide directory under `./bin`.
If you're on Microsoft Windows, you will most likely not be running the `nuclide` launch script anyway, so feel free to move the `fteqw.exe` into the root of the Nuclide directory, and run that as-is instead.
It will mount the game directories specified in the `default.fmf` file, which you can tweak as needed. [For more information, read the relevant documentation regarding launching Nuclide](Documentation/Launching.md)
## Building the Engine {#engine}
The **build_engine.sh** will do that for you. It will still ask you to have at least
a certain amount of dependencies installed (such as the **GCC**, **GNU make** and the **X11/SDL**
headers for your platform.
### Optional: Building release binaries
You'll have to manually go into `src/engine/engine` and issue:
```
$ make m-rel FTE_CONFIG=yourgameconfig
```
If you want to cross-compile to different platforms, you can pass the `FTE_TARGET` variable and select from **win32**, **win64**, **linux32**, **linux64** or **SDL2**.
For example, this will build a release binary of **The Wastes** for Win32, using the configuration specified inside `src/engine/engine/common/config_wastes.h`:
```
$ make m-rel FTE_CONFIG=wastes FTE_TARGET=win32
```
The resulting binary can be found inside the `src/engine/engine/release` directory.
**Note**: The **SDL2** target will require you to set the **ARCH** environment to the target of your choosing.
## Building the Level Editor {#editor}
Handled by **build_editor.sh**.
## Building Game-Logic {#game}
You can build the game source tree with **build_game.sh**.
The script also takes a parameter. If you specify:
```
./build_game.sh valve
```
then it will only build the game-logic for the `valve` directory.
Otherwise, it will iterate through all of the game directories, look for a Makefile and build its default target.
It'll try use the **fteqcc** binary that's in the *./bin/* directory.
So make sure to build run **build_engine.sh** first.
Some distributions may carry the **fteqcc** compiler, but it usually is a very ancient version
that's probably not going to build any of this.
## Custom Configuration {#config}
There's a **build.cfg** file with which you can tweak build parameters of the various **build_** scripts.
For example, this is where you select between X11 and SDL2 builds. There you can specify which engine revision
you want to build and also which plugins you want to build along with it.
It's well commented, so I encourage you to check it out. However on some platforms, changing those settings
might introduce additional setup/dependency steps.
## Additional Information {#notes}
The game-logic is written in QuakeC, it is thus platform and architecture independent.
You do not need to rebuild the logic for each and every platform.
The results will be identical.
If you don't plan on modifying the engine, then you can grab binaries
from [FTE's website](https://www.fteqw.org) and move the binaries for your platform into the root
directory of Nuclide.
## Dependencies
### Debian / Raspbian
#### FTE
![](application_osx_terminal.png) Nuclide is entirely game-logic oriented, so it only requires a working
QuakeC compiler. In our case [FTEQCC](https://www.fteqcc.org/). Which
you can also build with:
```
apt-get install libgl-dev gnutls-dev
$ make fteqcc
```
#### SDL2
The resulting binary `./fteqcc` will then be used to build the
game-logic related targets.
Besides a working **C** compiler, such as `gcc` or `clang`, the QuakeC compiler shouldn't need any other dependencies. [Click here for a full list of dependencies for the various optional components.](Documentation/Dependencies.md)
@note `make help` will always show a list of available targets, including their purpose.
## Keeping Up-To-Date
You can issue the following to check for updates of tools/dependencies:
```
apt-get install libsdl2-dev
$ make update
```
#### GLX / X11 (part of libsdl2-dev)
## Building Game-Logic {#build-game}
You can build games by running the following command:
```
apt-get install libx11-dev libxcursor-dev libxrender-dev
$ make game GAME=base
```
#### Plugin: ODE
Adjust the **GAME** argument to select which game you want to
build. The game `base` is the assumed, default target.
Usually, the resulting files are `progs.dat`, `csprogs.dat` and
(sometimes) `menu.dat`. Those are the libraries dealing with the
**Server**, **Client** and **Menu** aspect of the game respectively.
They are accompanied by name-matching `.lno` files. These contain
extra debugging information helpful to the engine. *They can be
stripped from a shipping build of your game.*
@note You do not need to rebuild the logic for each and every platform. The results will be identical, since QuakeC is not machine code!
## Building the Engine {#build-engine}
Issue the following to build a generic, non-branded version of the engine [FTE](https://www.fteqw.org/):
```
apt-get install autoconf automake libtool
$ make fteqw
```
#### Plugin: FFMPEG
Which you can then use to run 'Test Game' with `./fteqw +game base`. [For more information on launching games, mods, check out the page on Launching](Documentation/Launching.md).
@note Some engine features are only available as a plugin. See the section on plugins for details.
### Building a Branded Build {#build-branded}
If you want to build a custom version of the engine,
with custom branding and the ability to strip unneeded
functionality out of the binary, you can make a copy of
`ThirdParty/fteqw/engine/common/config_fteqw.h`, adjust it and save
it under your game directory as `engine.h`. When issuing the command:
```
apt-get install libavformat-dev libswscale-dev
$ make engine GAME=yourgame
```
### OpenBSD
It will then look for `yourgame/engine.h`, and build a copy of FTEQW
against it. The output will normally be something along the lines of
`yourgame_x64`.
#### FTE
@note The name can be changed by passing **NAME=YourGame** to the `make` program, or by placing a file named `PROJECT` in your game directory with a short name on the first line.
### Building plugins {#build-plugins}
You can build plugins for your game by specifying **NATIVE_PLUGINS** as an argument to the `make` command, like so:
```
pkg_add git
make plugins GAME=base NATIVE_PLUGINS="ode ffmpeg"
```
#### SDL2
However, once you've settled on a set of plugins for your game, you can list the contents of the **NATIVE_PLUGINS** string in a file named `PLUGINS` in your game directory.
@note For generic builds of **FTE** you can use the target **fteqw-plugins** instead of **plugins**. You shouldn't specify a **GAME** argument however.
## Building a dedicated server build {#build-dedicated}
![](server.png) If you want a minimal, dedicated server binary for your game that doesn't include all the code related to being a client, you can issue:
```
pkg_add sdl2
make dedicated GAME=yourgame
```
#### Plugin: FFMPEG
```
pkg_add ffmpeg
```
### Arch Linux
#### FTE
```
pacman -S make gcc Xorg git
```
#### Plugin: ODE
```
pacman -S zip automake autoconf
```
#### Plugin: FFMPEG
```
pacman -S ffmpeg4.4
```
*Note:* You will have to manually build this plugin due to FFMPEG breaking ABI between releases and Arch's rolling release nature.
1) Edit build.cfg and change `FFMPEG=YES` to `NO`
2) Browse to src/engine/engine
3) Run this command:
`make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/ffmpeg4.4/ AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"`
4) Copy over `fteplug_ffmpeg.so` to the `bin` folder where nuclide and the build scripts are.
And it will, much like a branded build, compile a dedicated binary specific to your game configuration.
#### SDL2
## Building the Level Editor {#build-editor}
```
pacman -S sdl2
```
#### WorldSpawn
```
pacman -S pkgconf gtk2 gtkglext
```
### OpenSUSE
#### Nuclide
```
zypper in git
```
#### FTE
```
zypper in make gcc gcc-c++ mesa-libGL-devel libgnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
```
#### SDL2
```
zypper in libSDL2-devel
```
#### GLX / X11
```
zypper in libX11-devel libXcursor-devel libXrandr-devel
```
#### Plugin: ODE
```
zypper in autoconf automake libtool zip
```
#### Plugin: FFMPEG
```
zypper in ffmpeg-4-libavformat-devel ffmpeg-4-libswscale-devel
```
#### Worldspawn
```
zypper in make gtkglext-devel libxml2-devel libjpeg8-devel minizip-devel
```
### Fedora
#### FTE
```
dnf install make gcc gcc-c++ mesa-libGL-devel gnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
```
#### SDL2
```
dnf install SDL2-devel
```
#### GLX / X11 (part of libsdl2-dev)
```
dnf install libX11-devel libXcursor-devel libXrender-devel
```
#### Plugin: ODE
```
dnf install autoconf automake libtool zip
```
#### Plugin: FFMPEG
*Note:* You will have to manually build this plugin due to FFMPEG breaking ABI between releases as well as install a custom repository since Fedora ships only latest versions of FFMPEG.
First, you will need to install the RPM Fusion if you don't have it. We recommend reading their official guide: https://rpmfusion.org/Configuration
Then, you can install the required version of FFMPEG:
```
dnf install compat-ffmpeg4-devel
```
Now to build:
1) Edit build.cfg and change `FFMPEG=YES` to `NO`
2) Browse to src/engine/engine
3) Run this command:
`make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/compat-ffmpeg4 AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"`
4) Copy over `fteplug_ffmpeg.so` to the `bin` folder where nuclide and the build scripts are.
#### Worldspawn
```
dnf install make pkgconf gtkglext-devel libxml2-devel libjpeg-turbo-devel minizip-devel
```
![](map_edit.png) See [the page dedicated to level editing](@ref radiant) for more information.

View file

@ -5,7 +5,7 @@ the work. They are generally prefixed **NS** (**Nuclide System**) so you can imm
if they're an internal component of Nuclide, or if it is part of something else.
You create the game by overriding the parts of Nuclide that you want to customize.
Want your player to move twice as fast? Then peek into the physics methods of NSClientPlayer
Want your player to move twice as fast? Then peek into the physics methods of ncPlayer
and override the virtual method responsible for that. That's how things generally work around here.
Try to avoid using private APIs. Things can and will break.
@ -17,28 +17,28 @@ These are the entity classes that you're generally encouraged to inherit to crea
### General purpose
Most map entities will be based off one of these. The difference can be felt in memory usage, networking and rendering speed. So if you wanted only basic entity logic without any fancy rendering or concept of hit detection an NSEntity may be enough.
However, if you want advanced rendering features, such as adjustable color, transparency and various other special effects you might want to start off with the NSRenderableEntity class as the basis for your entity.
Most map entities will be based off one of these. The difference can be felt in memory usage, networking and rendering speed. So if you wanted only basic entity logic without any fancy rendering or concept of hit detection an ncEntity may be enough.
However, if you want advanced rendering features, such as adjustable color, transparency and various other special effects you might want to start off with the ncRenderableEntity class as the basis for your entity.
- NSEntity
- NSRenderableEntity
- NSSurfacePropEntity
- NSPhysicsEntity
- ncEntity
- ncRenderableEntity
- ncSurfacePropEntity
- ncPhysicsEntity
### Trigger templates
These are templates for the two trigger types we currently support.
Check their respective Init methods to initialize them properly.
- NSBrushTrigger
- NSPointTrigger
- ncBrushTrigger
- ncPointTrigger
### NPCs/Monster/AI
Currently there's two types of monsters. The primitive ones that may move around and the more advanced talking ones.
- NSMonster
- NSTalkMonster
- ncMonster
- ncTalkMonster
## Game-logic classes
@ -46,19 +46,22 @@ Anything that doesn't specifically have to do with entities.
### Clients/Players
You are generally expected to implement a class named `player` in your game.
In most cases you will just want to inherit NSClientPlayer for that class.
You are generally expected to implement a class named `player` in your game using [decl](@ref decl).
In most cases you will just want to specify the `spawnclass` as being ncPlayer for that decl.
- NSClientPlayer
- ncPlayer
### Rules
Depending on the gamemode set by you in the server's Game_InitRules function, it should spawn a variant of NSGameRules and set the global `g_grMode` reference to that class you've initialized.
Depending on the gamemode set by you in the server's Game_InitRules function or value of `g_gametype` cvar, it should spawn a variant of ncGameRules and set the global `g_grMode` reference to that class you've initialized.
- NSGameRules
- ncGameRules
### Inventory
This needs to be completed.
The inventory is fully object oriented. The base inventory item classes consist of:
- NSWeapon (incomplete)
- ncItem
- ncWeapon
ncItem are *dormant* objects. They usually stay in the inventory without being able to select them, unless they're instant pick-ups like *Quake-style* health or ammo boxes.

View file

@ -1,24 +0,0 @@
# Constants
Often you want to be able to use aliases for values inside your **EntityDef** files.
For that, you can have a name/value pair mapping inside a text file named `scripts/constants.txt`.
```
// some comments here
WEAPON_NONE 0
WEAPON_CROWBAR 1
WEAPON_GLOCK 2
[...]
DEFAULT_NAME "Max"
```
And then you use the identifers in place of those constants. Similar to environment variables in the **UNIX** shell.
```
entityDef weapon_glock {
"spawnclass" "NSItem"
"inv_item" "$WEAPON_GLOCK"
[...]
}
```

View file

@ -1,7 +1,7 @@
# Contributing
If you'd like to contribute code: Awesome.
There's just 2 very short requirements.
There's just 1 very small requirement.
## Rule #1
@ -11,30 +11,10 @@ It's simple:
- Do not take code that is by anyone else that is not you.
## Rule #2
No submission or decompilation of third-party code. This is important if you want to recreate behaviour from another game.
- We do not decompile. We reverse-engineer by trial and error.
This is generally referred to as 'clean-room engineering'.
Most of the behaviour is rather predictable, other is not.
This is why some of the parts of Nuclide, which emulate entities/frameworks
from other games may feel a bit off. It's because it's all implemented by eye.
# Other notes
Game specific features need to be put into game-specific directories.
Unless other games benefit from this, keep it seperate to one of the game
sub-directories. This usually means it'll be part of another git repository too.
That's about it!
Code that was generated by a large language model or similar technology is not welcome, due to unclear status copyright.
# Saying Thanks
If you want to solely say thanks, the main developer of Nuclide **loves** receiving E-Mail. You can contact him at <mailto:marco@vera-visions.com> and let him know your thoughts.
If you'd like to donate to him via [PayPal](https://paypal.me/eukara) or [Patreon](https://www.patreon.com/eukara) you can do that too. That money pays for a lot of free services he provides that come with both [FTEQW](https://www.fteqw.org/) and **Nuclide**.
If you'd like to donate to him via [PayPal](https://paypal.me/eukara) or [Patreon](https://www.patreon.com/eukara) you can do that too. That money pays for a lot of free services/infrastructure that comes provided with both [FTEQW](https://www.fteqw.org/) and **Nuclide**.

View file

@ -1,8 +1,10 @@
# Dedicated Server
# Dedicated Server {#dedicated}
# Usage
## Usage
To initialize a dedicated server, you can run `./nuclide-ds -game yourGame`. It is generally advised to write and execute a server config file you have prepared ahead of time.
![](server.png) To initialize a dedicated server, you can [launch the engine](@ref launching) with the command-line argument `-dedicated` or run the dedicated server binary which you can [build yourself](@ref building) also.
It is generally advised to write and execute a server config file you have prepared ahead of time.
Here is an example:
@ -21,14 +23,14 @@ map dm_beck16 // start
You can then run the dedicated server like this:
`./nuclide-ds -game yourGame +exec server.cfg`
`./TestGame_x64 -dedicated +exec server.cfg`
In production, the exact same style of commands applies to release builds. So if you have a standard engine binary (**fteqwgl64.exe** or a branded executable) things will be identical.
Keep in mind to set any game specific console variables.
@note Keep in mind to set any game specific console variables.
# Remote Console (RCon)
## Remote Console (RCon)
In the above config, if you've set rcon_password to anything other than `""` you have access to remotely control the game server.
For example, you can (as a client, once connected) use the command `rcon yourPassword changelevel dm_beck16` to forcefully change the level on the server. Anything that's possible in a conventional dedicated server console is now accessible.
For example, you can (as a client, once connected) use the command `rcon yourPassword changelevel dm_beck16` to forcefully change the level on the server. Anything that's configurable in a conventional dedicated server console is now available.

View file

@ -0,0 +1,203 @@
# Dependencies {#deps}
Here we *attempt* to document the dependencies you may require to
build certain aspects yourself, on various different platforms.
## Debian / Raspbian {#deps-debian}
### FTEQW
```
# apt-get install libgl-dev gnutls-dev
```
### SDL2
```
# apt-get install libsdl2-dev
```
### GLX / X11 (part of libsdl2-dev)
```
# apt-get install libx11-dev libxcursor-dev libxrender-dev
```
### Plugin: ODE
```
# apt-get install autoconf automake libtool
```
### Plugin: FFMPEG
```
# apt-get install libavformat-dev libswscale-dev
```
## OpenBSD {#deps-openbsd}
### FTE
```
# pkg_add git
```
### SDL2
```
# pkg_add sdl2
```
### Plugin: FFMPEG
```
# pkg_add ffmpeg
```
## Arch Linux {#deps-arch}
### FTE
```
# pacman -S make gcc Xorg git
```
### Plugin: ODE
```
# pacman -S zip automake autoconf
```
### Plugin: FFMPEG
@note You will have to manually build this plugin due to FFMPEG breaking ABI between releases and Arch's rolling release nature.
First install the legacy version of **ffmpeg**:
```
# pacman -S ffmpeg4.4
```
Then browse to `ThirdParty/fteqw/engine` and run this command:
```
$ make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/ffmpeg4.4/ AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"
```
Last, copy over `fteplug_ffmpeg_*.so` to the root directory where the
engine binaries (and other plugins) are.
### SDL2
```
# pacman -S sdl2
```
### WorldSpawn
```
# pacman -S pkgconf gtk2 gtkglext
```
## OpenSUSE {#deps-suse}
### Nuclide
```
# zypper in git
```
### FTE
```
# zypper in make gcc gcc-c++ mesa-libGL-devel libgnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
```
### SDL2
```
# zypper in libSDL2-devel
```
### GLX / X11
```
# zypper in libX11-devel libXcursor-devel libXrandr-devel
```
### Plugin: ODE
```
# zypper in autoconf automake libtool zip
```
### Plugin: FFMPEG
```
# zypper in ffmpeg-4-libavformat-devel ffmpeg-4-libswscale-devel
```
### Worldspawn
```
# zypper in make gtkglext-devel libxml2-devel libjpeg8-devel minizip-devel
```
## Fedora {#deps-fedora}
### FTE
```
# dnf install make gcc gcc-c++ mesa-libGL-devel gnutls-devel alsa-devel libopus-devel speex-devel libvorbis-devel
```
### SDL2
```
# dnf install SDL2-devel
```
### GLX / X11 (part of libsdl2-dev)
```
# dnf install libX11-devel libXcursor-devel libXrender-devel
```
### Plugin: ODE
```
# dnf install autoconf automake libtool zip
```
### Plugin: FFMPEG
@note You will have to manually build this plugin due to FFMPEG breaking ABI between releases as well as install a custom repository since Fedora ships only latest versions of FFMPEG.
First, you will need to install the RPM Fusion if you
don't have it. We recommend reading their official guide:
https://rpmfusion.org/Configuration
Then, you can install the required version of FFMPEG:
```
# dnf install compat-ffmpeg4-devel
```
Now to build:
1. Browse to `ThirdParty/fteqw/engine`
2. Run this command:
```
$ make plugins-rel NATIVE_PLUGINS="ffmpeg" AV_BASE=/usr/include/compat-ffmpeg4 AV_LDFLAGS="-l:libavcodec.so.58 -l:libavformat.so.58 -l:libavutil.so.56 -l:libswscale.so.5"
```
Last, copy over `fteplug_ffmpeg.so` to the root directory where the
engine binaries (and other plugins) are.
### Worldspawn
```
# dnf install make pkgconf gtkglext-devel libxml2-devel libjpeg-turbo-devel minizip-devel
```

View file

@ -0,0 +1,238 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.9.3 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="concepts" visible="yes" title="">
</tab>
<tab type="interfaces" visible="yes" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="structs" visible="yes" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="yes" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<detaileddescription title="About this class"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<detaileddescription title=""/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<detaileddescription title=""/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<functions title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<functions title=""/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View file

@ -1,45 +0,0 @@
# EntityDef
## Overview
In **id Tech 4**, we have been introduced to external entity definitions. They are pretty straightforward by merely being a set of default values for an existing entity class.
This can be used in a variety of ways.
- Create new entity classes with new behaviour without any code
- Create a base class that other entityDefs can inherit from
- Create prefabs that get updated across all maps
This system can also be used in combination with [MapTweaks](Documentation/MapTweaks.md), where an entityDef is used instead of a base class depending on the parameters you decide to test.
## Syntax
Let's take a look at an example **EntityDef**:
```
entityDef item_health_small {
"spawnclass" "item_health"
"spawnflags" "1"
}
```
This is from the port of *Deathmatch Classic*, and will ensure that **item_health_small** from *Quake III Arena* gets spawned as an **item_health** with its *spawnflags* set to the one that will make it a small health pickup.
You can have as many key/value pairs as you like. However, you can only specify one *spawnclass* and you cannot do circular inheritance.
## Special Keys
These are reserved keys and are meant to be used by the **build_game.sh** script to generate an entities.def file for your game.
| Key | Description |
|--------------------|------------------------------------------------------------------------|
| editor_usage | Description text used by the editor. |
| editor_model | Model to use in the editor. |
| editor_var **KEY** | Description text for the specified key. |
| editor_color | Normalized color vector defining the bounding box color in the editor. |
| editor_mins | Vector defining the mins of the entity bounding box. |
| editor_maxs | Vector defining the maxs of the entity bounding box. |
# References
- [id.sdk page on Entity Defs](http://icculus.org/~marco/notmine/id-dev/www.iddevnet.com/doom3/entitydefs.html)

View file

@ -156,6 +156,8 @@
[func_traincontrols](@ref func_traincontrols)
[func_useableladder](@ref func_useableladder)
[func_vehicle](@ref func_vehicle)
[func_vehiclecontrols](@ref func_vehiclecontrols)
@ -192,6 +194,8 @@
[info_intermission](@ref info_intermission)
[info_landmark](@ref info_landmark)
[info_node](@ref info_node)
[info_node_air](@ref info_node_air)
@ -214,8 +218,16 @@
[infodecal](@ref infodecal)
[item_eyescanner](@ref item_eyescanner)
[item_food](@ref item_food)
[item_generic](@ref item_generic)
[item_healthcharger](@ref item_healthcharger)
[item_recharge](@ref item_recharge)
[light](@ref light)
[light_dynamic](@ref light_dynamic)
@ -248,6 +260,8 @@
[multisource](@ref multisource)
[npc_furniture](@ref npc_furniture)
[path_corner](@ref path_corner)
[path_track](@ref path_track)
@ -282,6 +296,8 @@
[point_trigger](@ref point_trigger)
[point_viewcontrol](@ref point_viewcontrol)
[prop_dynamic](@ref prop_dynamic)
[prop_physics](@ref prop_physics)
@ -296,6 +312,18 @@
[random_trigger](@ref random_trigger)
[reserved_spot](@ref reserved_spot)
[script_brushmodel](@ref script_brushmodel)
[script_model](@ref script_model)
[script_origin](@ref script_origin)
[script_struct](@ref script_struct)
[script_vehicle](@ref script_vehicle)
[scripted_sentence](@ref scripted_sentence)
[scripted_sequence](@ref scripted_sequence)
@ -308,6 +336,8 @@
[target_cdaudio](@ref target_cdaudio)
[target_speaker](@ref target_speaker)
[trigger_auto](@ref trigger_auto)
[trigger_autosave](@ref trigger_autosave)

View file

@ -1,72 +1,48 @@
# Filesystem
## Launching
## Virtual Filesystem
The `nuclide` shell script is the launcher.
The engine binary attempts to initialize a virtual filesystem within a **game directory**. That is a directory in which your entire game lives in. In *id Software* their game **Quake** that directory was named **id1/**, in *Valve* their game **Half-Life** it was **valve/**.
It sets **$PATH** to include the directory `bin/` which contains the engine that
you've built with `build_engine.sh`.
You will be tasked with naming your own game directory, if you were to build your own game.
When nuclide is run and executes the engine, it'll first read `default.fmf` which
is a manifest file the engine reads. It is updated occasionally.
It defines which directories to mount in the virtual filesystem of the engine
and has a document entirely dedicated to itself. For that please read:
```
src/engine/specs/fte_manifests.txt
```
## Loading Games
On its own, Nuclide launches the game directory `base/`, unless you tell it otherwise:
```
./nuclide -game mygame
```
Will load `mygame/` instead of `base/`.
You can also load multiple additional directories in a specific order by specifying
multiple `-game` command-line arguments.
It will still load the other `BASEGAME` entries listed in the default.fmf.
You can even load your own manifest file over default.fmf, by passing
```
./nuclide -manifest mymanifest.fmf
```
## Virtual-Filesystem
The example **Nuclide** game, called **Test Game** is stored in **base/**, and is thus often referred to as 'base'.
When a game is mounted, we're either looking for **loose files** (loaded last), or
**archives** the engine supports.
The Quake .pak archive format, or zip archives with the pk3 and pk4 extensions are supported.
Upon initializing the filesystem they are enumerated alphabetically and then loaded in order.
@note You can switch games using the `game` console command.
Directories with the .pk3dir extensions are treated as if they were .pk3 archives.
The editor also supports .pk3dir directories.
## Archives {#archives}
Once the game has loaded a game directory, it'll load the persistent menu.dat into our QuakeC
![](compress.png) The Quake [pak archive](https://quakewiki.org/wiki/.pak) format, or [zip archives](https://en.wikipedia.org/wiki/ZIP_%28file_format%29) with the **pk3** and **pk4** extensions are supported.
Upon initializing the filesystem they are enumerated alphabetically and then loaded in order, thus the filename affects the load order of archives.
Directories with the .pk3dir extensions are emulated, acting as if they were .pk3 archives. **We recommend you use them to organize your development files.**
### Protected archives
Protected archives always start have the prefix **pak**[...] and **cannot** be downloaded by connecting
to a server game that has them.
**We suggest you use this for any copyrighted data.**
## Game-logic behaviour
When you spawn a map, you create a server (running `progs.dat`) which will distribute its own client-side game-logic (`csprogs.dat`).
But before this, when the client (not the server) has loaded a game directory, it'll load the persistent `menu.dat` into its own QuakeC
virtual machine.
It' always running, you can make your own by modifying `src/menu-fn/`, `src/menu-vgui/`
or writing your own module.
It's always running, unlike `progs.dat` and `csprogs.dat` code which gets reloaded between map changes.
You can use this to your advantage by restarting levels in order to reload game logic, or to reload entity definitions.
## Archives
In order to restart the menu, you manually issue `menu_restart` via the **engine console** (SHIFT+ESC).
Protected archives always start have the prefix **pak**[...] and cannot be downloaded by connecting
to a server that has them.
**Use this for any copyrighted data.**
## Restarting the file-system during the game
When you spawn a map, you create a server which will distribute its own client-side game-logic.
You can initiate a refresh of the virtual filesystem by issuing `fs_restart` in the **engine console**.
It's advised that you do not pack **csprogs.dat** and **progs.dat** into a protected archive.
## Reloading assets
## Nuclide specific formats
Nuclide contains many custom definition files that are not engine specific.
`.efx`, `.font`, `.sndshd` and `.way` to name a few.
The game-logic mostly handles them and can thus be, in theory, extended by you.
You can reload image and/or model assets by issuing `vid_reload` in the **engine console**. While the map geometry may reload, for entity changes you will have to issue a full `map_restart` in the **engine console** to see them reload.

View file

@ -0,0 +1 @@
Nuclide is a project by [Vera Visions, L.L.C.](https://www.vera-visions.com/)

View file

@ -0,0 +1,177 @@
# Getting started
## How to get the latest version {#how}
You clone the Nuclide git repository first. There's multiple places to get it, one such place may be [code.idtech.space](https://code.idtech.space/):
`git clone https://code.idtech.space/vera/nuclide`
![](application_osx_terminal.png) You can then update the git repository as you normally would. Using `git pull`, or the built-in `make update` which will additionally update third-party repos and - when specified - a game directory.
If you need to build engine binaries, you can [get started on building the engine and the rest of the toolchain](@ref building) now.
Alternatively, you can also move in the official [FTE](https://www.fteqw.org/) binaries into the **Nuclide** directory to get started *without* bootstrapping your own engine + QuakeC compiler.
@note C programming knowledge is not required to use Nuclide itself.
## Running the game
Once you've built your engine binary or grabbed an existing compile from [FTE](https://www.fteqw.org/) its website, you should [proceed building the game-logic](@ref build-game).
You can then [run the client](@ref launching) and you should see the game window open right away.
![Test Game - aka Nuclide 'Base'](nuclide-base.png)
## Modifying the game
![](brick.png) In **Nuclide**, the main design goal is to have **Objects** included that do most of the work for you. You then use external, plain text files (referred to as 'decl') to fine-tune the various aspects of them.
Just because you need a dedicated spawn point entity for a fearful enemy doesn't mean you have to recompile the source code. You can simply make a decl that declares itself to be a spawnpoint with a given classname.
![](table.png) You can [read up on decls in these docs](@ref decl) to find out how you can take advantage of them.
## Debugging {#debugging}
![](bug.png) The engine comes equipped with several commands useful for debugging.
Nuclide also contains some commands of its own that aim to make your work easier. Let's go over some important ones.
### Console {#console}
The console is the main interface to debugging the game. So one needs to learn how to invoke it. It can be opened by pressing **Shift** + **Escape** on your keyboard.
From here on you can find out the version of your engine by typing `version` and pressing **ENTER**:
![The Console](nuclide-console.png)
Which may be useful in determining which engine version you are using, in case you need to file bug reports with the engine. Make sure to attach a copy of your engine build config if you happen to use one.
Some other useful commands are `condump logfile.txt`, `find`, `clear` and `quit`. The console has support for search and auto-completion so take advantage of it to save time! You can also use the **scroll wheel** on your *mouse* or *trackball*, as well as the **Page Up**, **Page Down**, **Control + Home** and **Control + End** keys on your *keyboard*.
### Watchpoints
You can set watchpoints using `watchpoint_ssqc` and `watchpoint_csqc` for @ref SSQC and @ref CSQC respectively.
To set a watchpoint on an entity its field, like the 1st player in a singleplayer game, you could do this to track their health:
```
watchpoint_ssqc 1.health
```
@note **The number in front of the '.health' field is the entity number.** You can find those out with debug viewers such as `r_showfields 1`, or the output in the console when `g_logLevel` is set to `3`. There are some more commands listed below that will help you identify entity numbers.
### Poking
Much like with watchpoints, we can view entity fields as well as manipulate them right from the console.
```
poke_ssqc 1.health=42
```
Will set the 1st player's health to `42`. If you do not assign a value it'll instead print out the field its current value.
### Entity Data
You can list the entity data, specific to the level you are on, like so:
```
listSpawnData 248
```
And the output will look a lot like:
```
]/listSpawnData 248
Spawn data for func_breakable (248):
{
"model" "*13"
"origin" "-130 -456.53 190"
"physdamagescale" "1.0"
"minhealthdmg" "0"
"disablereceiveshadows" "0"
"rendercolor" "255 255 255"
"renderamt" "255"
"rendermode" "0"
"renderfx" "0"
"pressuredelay" "0"
"explodemagnitude" "0"
"spawnobject" "0"
"nodamageforces" "0"
"gibdir" "0 0 0"
"explosion" "0"
"material" "0"
"health" "1"
"propdata" "0"
"PerformanceMode" "0"
"ExplodeRadius" "0"
"ExplodeDamage" "0"
"disableshadows" "0"
"classname" "func_breakable"
}
```
Much like with *watchpoint* and *poke* commands, you need to specify which entity id you want to query. That is the only unique identifier every entity has.
### List Named Triggers
In your levels you may want to debug some of the map-logic in isolation. You can get a list of all available named entities set up to trigger events like so:
```
listTargets
```
The output will look a lot like this:
```
]/listTargets
214: ladder1 (func_useableladder)
250: chimes (info_target)
259: powerbox_button (func_button)
260: output_0 (triggerminion)
261: output_0 (triggerminion)
262: output_0 (triggerminion)
263: output_0 (triggerminion)
264: output_0 (triggerminion)
265: output_0 (triggerminion)
266: output_0 (triggerminion)
267: output_0 (triggerminion)
268: powerbox_spark (env_spark)
269: powerbux_hurt (trigger_hurt)
270: powerbox_beam (env_beam)
271: powerbox_light (light)
272: scary_sound (info_target)
274: electro_hum (info_target)
275: beam_start (info_target)
276: beam_end (info_target)
396: pigeon_sound (info_target)
```
Output format consists of `[entity-id]: targetname (classname)`. You can then use this information to **send messages** directly to any of them.
### Sending Messages
#### Conventional 'Trigger' Impulse
You can send a simple **trigger impulse** to any named entity:
```
trigger powerbox_light
```
And it will respond as if it was triggered naturally.
#### Advanced Input Signals
Sometimes, you may also want to trigger a specific **input** on an entity, which can be done with the `input` command like this:
```
input 248 SetColor "255 128 0"
```
Where the syntax is `input [entity-id] [input name] [data string]`.
@note For the list of available **Inputs**, check the documentation for your desired object. For example: func_areaportal
### Logging
By default, most logging in the console is limited to *errors* and *warnings*. They are colored red and yellow in the output respectively.
You can output additional information, which will be useful during object development by setting `g_logLevel` to the value of `3`. You will then see additional messages appear when entities receive signals, or run complicated logic and states of success.

View file

@ -29,7 +29,7 @@ A lot had been learned about prediction and taking full advantage of the
custom networking available in **FTEQW**, but new features have also been
added to the engine to take full advantage of what the content had to offer:
Features like interacting with [OpenAL's EAX extension](EFX.md), [model-events](VVM.md), support
Features like interacting with [OpenAL's EAX extension](@ref efx), [model-events](VVM.md), support
for WAD3 decal parsing and countless QuakeC extensions were all added by
either Spike (FTEQW Author) or eukara himself to make everything possible.

31
Documentation/Icons.md Normal file
View file

@ -0,0 +1,31 @@
# Icon Glossary
Throughout this documentation, you will come across a variety of topics represented by icons.
- ![](application_osx_terminal.png) [Console](@ref console), often seen when the topic of command execution pops up.
- ![](brick.png) Object. Like an instance of an ncEntity.
- ![](bug.png) [Debugging help/options](@ref debugging), or bug related comments.
- ![](color_swatch.png) [Materials](@ref materials)
- ![](compress.png) @ref archives
- ![](computer.png) [AI opponents](@ref ncMonster), including [bots](@ref ncBot).
- ![](controller.png) Controller input, usually handled by [SDL](https://www.libsdl.org)
- ![](film_save.png) Demo recording. A universal replay file.
- ![](images.png) Textures, usually inputs to [Materials](@ref materials)
- ![](keyboard.png) Keyboard input.
- ![](lightbulb.png) [Lighting](@ref mappingtips_lighting). From static lightmaps controlled by the @ref light entity to light_dynamic to point_spotlight.
- ![](map.png) Map, the name given to our levels in which gameplay occurs.
- ![](monitor.png) Display, representing the whole physical size of the game window.
- ![](mouse.png) Mouse, usually seen when referring to actions to be done with a pointing device akin to a mouse, or trackball.
- ![](music.png) Music, all about the subsystem handling looped music and stingers.
- ![](package.png) [Package, managed by the built-in update manager.](@ref updates)
- ![](plugin.png) @ref progs, games are made up of a collection of them.
- ![](server.png) [Dedicated server, game server.](@ref dedicated)
- ![](sitemap_color.png) @ref shaders
- ![](sound.png) [Sound samples, inputs to SoundDef.](@ref sounddefs)
- ![](table.png) [Dictionaries](@ref ncDict) containing key/value pairs. Like @ref decl for @ref entitydef and @ref sounddefs.
- ![](table_edit.png) Editing plain text files.
- ![](clock.png) [Timers](@ref ncTimer), used to schedule events in advance.
- ![](plugin_go.png) [AddonC](@ref addonC) is our server plugin system.
- ![](monitor_go.png) [HudC](@ref hudC) powers our hot-pluggable Heads-Up-Display in our client-game.
- ![](map_go.png) [MapC](@ref mapC) handles maps-specific tasks and logic.
- ![](script_go.png) [RuleC](@ref ruleC) is responsible for global set of game-rules.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View file

@ -1,68 +1,27 @@
# Launching
# Launching {#launching}
## For development...
If you [built a custom branded version of the engine](@ref build-engine), you can run that as is.
For development, use the `nuclide` launch script inside the root directory.
Using a generic [FTE](https://www.fteqw.org/) binary however, you need to specify the game directory.
You run `./fteqw` with a parameter specifying the game directory:
```
$ ./nuclide
$ ./fteqw +game base
```
Running it on its own will mount only the directory `platform/`. As that's the default defined inside the file `./default.fmf`.
You can mount an additional mod over it like so:
You can dispatch [console](@ref console) commands to be executed once the client is running by appending them to the command-line as launch parameters, prefixed with the `+` character, as seen above.
```
$ ./nuclide -game some_other_mod
./TestGame_x64 +set g_gametype some_mode +devmap some_level
```
If you wanted to mount multiple game dirs, you could in theory do it like so:
```
$ ./nuclide -game first_mod -game second_mod -game third_mod
```
And it'll load those directories in order.
However, if you'd like to be very specific in how a game is run/branded/launched
you should really use **FTE Manifest** files.
Simply plop one into your game directory with the name `manifest.fmf`, then launch
nuclide like so:
```
$ ./nuclide first_mod
```
and it will load `first_mod/manifest.fmf`. You can supply arguments to it by putting them into the second parameter with quotes like so:
```
$ ./nuclide first_mod "-window +set sv_cheats 1"
```
However, we advise you only do this for development. If you want proper multiplayer compatibility (slightly different filesystem mount setups can confuse client-server negotation) please use the built-in **Custom game** menu to ensure maximum compatibility to other clients.
If you are running a dedicated server and have issues with multiple game directories, check the value of the cvar `sv_gamedir` on the server. It is meant to be a semicolon separated list of game directories, if multiple ones are supposed to be mounted.
## For release...
You'll want to compile a custom build of the engine with your branding.
Inside `src/engine/engine/common/` you can find a config file named `config_wastes.h`,
which is a good example of how you can customize your engine binaries and filesystem mount-points.
That way you **avoid** shipping a default.fmf file.
**How to compile a custom config build**: You pass `FTE_CONFIG=wastes` to the make environment when building an engine binary - if you wanted to build with the `config_wastes.h` file. [For more information check out the building section](Building.md)
## Mod/Game Setup
For mods to show up in the "Custom Game" menu, we have to either find a manifest
file, or a liblist.gam, or a gameinfo.txt inside the respective mod directory.
For mods to show up in the "Custom Game" menu, Nuclide has to either find a `liblist.gam` file, a [FTE-specific](https://www.fteqw.org/) manifest
file, or , or a [Source Engine](https://web.archive.org/web/20110724220714/http://source.valvesoftware.com/) styled `GameInfo.txt` inside the respective mod directory.
It'll scan .pk3 and .pk4 archives, as well as loose files in the mod directory,
however it will not search inside any sub-directories.
It is trying to look inside the dlcache/ folder, but the engine is currently
restricting that.
It'll scan [resource archives](@ref archives), as well as loose files in the mod directory,
however it will *not search inside any sub-directories*.
A liblist.gam file can look something like this:
@ -73,29 +32,7 @@ A liblist.gam file can look something like this:
trainingmap "traininglevel"
```
But more definitions are available.
Check src/menu-fn/m_customgame.qc's customgame_liblist_parse() function to stay
up to date regarding all the supported liblist variables that can be set.
You can find the types of key/value pairs a game can use to identify itself in GameLibrary_LibListParse()
under `src/platform/gamelibrary.qc`.
GameInfo.txt files are supported too. They originate from the Source Engine
filesystem, however there's no concept of Tools and Game AppIDs as Nuclide does
not link against Steamworks.
Support for such definitions is complementary and I'd advise not to expect it
to be feature complete. It has a concept of inheriting multiple paths as defined
by the specification.
If you need more control, you can use manifest files. Similar to the default.fmf
that's in the root Nuclide source tree. You can set liblist entries like this
inside of them:
```
-set gameinfo_game "My Cool Mod"
-set gameinfo_version "1.0"
-set gameinfo_startmap "e1m1"
-set gameinfo_trainingmap "traininglevel"
```
Please name the manifest the same as the mod/game dir. For example if your game
its directory is named "foobar" name your manifest "foobar.fmf".
That's all there is to know about mod-detection in Nuclide its menu progs.
Those settings alone can alter quite a bit of the menu options and branding/presentation of your game.

View file

@ -0,0 +1,175 @@
# Level Editing {#radiant}
![](map_edit.png) **Nuclide** does not come with a built-in level editor, you're encouraged to use one of many variety of editors maintained by the id Technology enthusiast community.
However, we have integrated gamepack building support for [GtkRadiant](http://www.icculus.org/gtkradiant/).
If you are new to level design or want to brush up on your knowledge, [look no further than GtkRadiant's documentation page for level designers](https://icculus.org/gtkradiant/documentation.html).
@note When we refer to *Radiant* we are usually referring to *GtkRadiant*, but it will usually also apply to other versions of Radiant such as **NetRadiant**, **NetRadiant-Custom**, **DarkRadiant** etc.
If you have issues with **GtkRadiant** or any other editor, [please file bugs with said project](https://www.github.com/TTimo/GtkRadiant/issues) and **not** with **Nuclide**.
## Building integrated Radiant
![](application_osx_terminal.png) If your workstation has all the dependencies (`pacman -S git scons libxml2 gtk2 freeglut gtkglext subversion libjpeg-turbo`) installed, you can build the default version of **Radiant** like so:
```
make radiant
```
And then run it using the launcher at `./radiant`.
@note NetRadiant-Custom is also available to build with Nuclide integration. Specify `netradiant-custom` as the target.
You will probably want Nuclide's build system to generate a game pack for that installation of **Radiant**.
This can be achieved by running:
```
make defs [GAME=base]
```
Where `GAME=base` is used to specify which game to build. That should match the name of your game directory.
After that, you will be able to select your game from within **Radiant**.
@note If you plan on using a legacy BSP format using WAD texture archives, the target `defs-wad` can be used instead of `defs`.
![Radiant Launch Setup](radiant-setup.png)
## BSP Compiler
The generated gamepack will attempt to build with `vmap`. You can change this of course, by setting up your own toolchain under **File > Project settings...**.
![Radiant Project Settings](radiant-settings.png)
## Building your level
In the *menu-bar* you'll find the **Bsp** menu, under which a few choices will be visible:
![Radiant Project Settings](radiant-build.png)
This is more or less what the default build options for your level will look like.
Clicking any of them will result in your **map** file being compiled into a **bsp** file, which contains the final level geometry, entity data and lighting built into one blob file.
@note Depending on your level size and complexity, this may take a while. You can see the progress in your Terminal if you've run *Radiant* in one.
![](map.png) The final **bsp** file output will be alongside your **map** file.
Ensure it's within your `<gamedir>/maps` directory so you can test it.
To run your level, execute this in the engine/game console (SHIFT+ESC):
```
devmap nameofyourlevel.bsp
```
And that's all there is to know about getting started building levels with Radiant and Nuclide.
# Level Editing: Tips and Tricks
## Lighting: Best Practices {#mappingtips_lighting}
![](lightbulb.png) Here we'll run down the practices of lighting your map using
WorldSpawn and vmap.
### Basic Rules {#mappingtips_lighting_rules}
- Point lights are hard to maintain, use surface lights (either
@ref vmap_surfaceLight or light_surface.
- light_environment will do the bulk of
the world lighting, it should even be used in afternoon and dark
settings
- Avoid ambient lighting, unless you know exactly what you want, or
you're in a completely interior-only map
### Global settings {#mappingtips_lighting_settings}
The light_environment entity will do the bulk
work. It emits light from any sky surface, such as `common/skyportal`.
The amount of samples specify how many **passes** are done. This will be
*evened* out to match the desired **intensity**, so increasing samples
does **not** make the map brighter.
Using more than 1 sample is useful if you want less harsh-shadows. Even
a value of 4 with a `sunspreadangle` of e.g. 5-10 degrees is sensible
for day-time maps. It makes them look less artifacting too. The theory
is, the cloudier the world is, the softer the shadows are - so we need
more **samples** and a `sunspreadangle` that's wider to accommodate
that.
The `sunspreadangle` will determine how far apart the different samples
will be spread. E.g. if you set it to `0` it will do nothing. Every
light_environment sample will take place on the exact same spot, from
the same angle. However if you set it to 360 (the maximum amount), each
sample will spread out to get a full 360 coverage of the map. Resulting
in a lightmap without any real contrasting shadows.
### Which light_environment color to use? {#mappingtips_lighting_color}
99% of the time it's going to be white. Let `_ambient` inside your
light_environment tint the shadows the color of the sky, let radiosity
do its job. Radiosity can't do its job if the sun color is non-white.
**The effects of radiosity will be barely visible using a non-white
light_environment color.**
**Case in point**: The overwhelming tint of orange/brown in id Software's game Quake II.
### Ambient color? {#mappingtips_lighting_ambient}
Set `_ambient` in your light_environment to whatever the color of the
sky is set to. This determines the color of the shadows cast by the
light_environment. **This does not create a minimum ambient intensity in
the process**
### Minimum light intensity {#mappingtips_lighting_minlight}
In your worldspawn entity keys, you can add a `_minlight` intensity value, as well as a `_minlight_color` value to an entity.
Then, any lightmap based lighting will ensure to be at least that level of brightness.
This is not something you want to use for anything meant to look natural.
### What about the worldspawn '_ambient' key? {#mappingtips_lighting_worldspawn}
The absolute lighting level of the map is raised. This has the tendency
to flatten the difference between light and shadow. The dynamic range of the light is
affected negatively as a result.
It raises the lighting level-wise, but keeps the light values of each
entity/sky/shader intact.
@note You will never achieve truly black areas in your map after this. Be
aware of that.
Only use this as a last resort in case you want to make sure there are no black/dark areas in your level.
### What about the worldspawn '_floodlight' key? {#mappingtips_lighting_flood}
With floodlight, light becomes darker in closed spaces and brighter in
wide open spaces.
The worldspawn key for that is `_floodlight`, with you specifying **5 whitespace separated values** for the key:
```
<red color> <blue color> <green color> <travel distance> <intensity>
```
The side effect is that it'll obviously act as a contrasting knob. It
**does not fix spaces where light wasn't present to begin with**!
@note There are very few artistic use cases for this. However, if your map is
looking very dull/flat, it could help a lot.
## Should I use radiosity? And if yes, how many bounces? {#should_i_use_radiosity_how_many_bounces}
**Yes, you should use radiosity. It fixes most problems with lighting your level!**
Valve's BSP compiler used for *Half-Life 2* cast light rays with a maximum of 8 bounces, which is sensible. You
can even set it to **100** and it'll stop once photons lose their energy.
The alternative to *radiosity* is *direct lighting*, which is what is used in the original *Quake*.
The difference between direct lighting and radiosity is that *when the latter light hits a wall, it reflects and bounces around the room*, although it loses some of its energy.
It will also absorb some of the color of the surface it bounces against.
The end result is you can illuminate environments more evenly.

View file

@ -1,88 +0,0 @@
# Overview
Welcome to the documentation for Nuclide!
This is a software development kit (SDK) and development environment created by [Vera Visions, L.L.C.](https://www.vera-visions.com/). We want to share it with everyone to avoid duplicate effort and in the hopes that it is useful to someone else.
## What this project is {#what}
The Nuclide project produces a freely available game-logic component and
development platform on top of [FTEQW](https://www.fteqw.org); which is the engine we happen to use.
**The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.**
The goal is to create a modern research base for new advancements, as well
as to have a stable base with a decent API for making games.
It comes with a simple example game (simply referred to as 'Base') and some test maps. There's also some other, third-party example projects.
General feature overview:
- The 'missing' SDK for engines like FTEQW
- Support for client-side predicted movement, weaponry and vehicles
- Documented APIs for everything you need to interface with the engine
- APIs and Frameworks for managing updates, mods, servers, and platform specific features
- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games
- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system
- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides
- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces
- Designed to be familar to developers coming from GoldSrc/Source
- VR/XR aware codebase
- All permissively licensed
### 1. Why might I want to use it? {#why}
You might be migrating from an engine that is no longer being licensed and don't want to learn a new engine and toolchain.
You might want to develop a game using a lot of complex and well-tested objects
which might be tedious to implement on your own.
You might want to run or make modifications for a game using Nuclide and need full
control over what you can do.
### 2. How free is Nuclide? {#license}
Everything in Nuclide is **free software**. The copyright terms for the game-logic are
very permitting. Nuclide *does not use the GPL* as a point of reference in terms of license, it instead uses a **ISC-like license**. This means you can use, copy, modify and
distribute the code and work resulting from it for any purpose.
**Please read the very short 'LICENSE' document for details.**
### 3. What are the alternatives? {#alternatives}
Implementing systems such as prediction, complex map objects and entities on
your own, from scratch - or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**.
### 4. Any example projects? {#examples}
- [The Wastes](https://store.steampowered.com/app/793670) is a commerical game built using Nuclide.
- [FreeHL](https://www.github.com/eukara/freehl) is a free-software, clean-room clone of Half-Life: Deathmatch also built using Nuclide.
- [FreeCS](https://www.github.com/eukara/freecs) exists in the same vein as FreeHL, but targetting a recreation of Counter-Strike v1.5 (mod version) specifically.
## Getting started {#prerequisites}
First of all, you want to be sure this is what you want to get into.
If you do posess a basic knowledge of the following:
- The C programming language
- Debugging a native application
- Makefiles
- Compiling your own binaries
- Concept of public and private APIs
- QuakeC
Then you will have a good time.
We strive to keep the codebase portable and conform to open standards wherever possible.
This means that if you develop on Windows, you probably want to install something like WSL or even [Cygwin](https://www.cygwin.com/) to make this bearable.
Please don't ask us how to use WSL or Cygwin. We do not provide support for either. We do not develop on Windows.
**This is a development kit and a development environment. This is not a game.**
## Actually getting started {#how}
You clone the Nuclide git repository first. There's multiple places to get it, one such place may be GitHub:
`git clone https://github.com/veravisions/nuclide`
And then you can [get started on building the engine and the rest of the toolchain](Building.md). Alternatively, you can also move in the official FTEQW binaries into the Nuclide directory to get started without bootstrapping your own engine + QuakeC compiler.

View file

@ -1,36 +0,0 @@
# MapTweaks
## Overview
This is a very customizable system that applies changes to levels/maps depending on a variable amount of parameters. It was invented specifically for Nuclide and designed to work together with [EntityDefs](Documentation/EntityDef.md).
## Syntax
All MapTweaks are defined within `scripts/maptweaks.txt`.
Let's take a look at an example **MapTweak**:
```
hldm_tweak
{
when-cvar deathmatch equals 2
when-serverinfo *bspversion equals 30
replace weapon_gauss info_null
replace weapon_egon info_null
}
```
The `hldm_tweaks` is just a user-defined name. It doesn't affect functionality.
The `when-cvar` and `when-serverinfo` lines are **checks**. each one is checked individually and only if all are positive will the `replace` lines take effect.
You can have as many lines in there as you like.
Other than `equals`, you can also use one of the following keywords when comparing values:
- **less-than**
- **greater-than**
- **is-not**
At this time, `when-cvar` and `when-serverinfo` only do comparisons on numbers. So you cannot check for strings at this time.

57
Documentation/MapTypes.md Normal file
View file

@ -0,0 +1,57 @@
# Map Making
## Which Format You Should Use
That depends on the job. If you want to work with a modern format, comparable to that of a 2004 game engine and beyond, any variant of Quake III Arena's BSP format can do.
We aim to support everything equally.
For a more authentic, 1990s experience you may want to use Quake II's format instead.
We have our own variant of the BSP format, which can be compiled by using [vmap](VMap.md).
### Quake BSP
This is the default format that all the Quake tools, such as [ericw-tools](https://ericwa.github.io/ericw-tools/) compile into. If you exceed limits, they generally will generate a **"BSP2"** file, which is something our engine also understands. The original engine and format only did monochrome color. This is no issue any longer because modern compilers output so called **lit** files, which contain colored lightmaps externally. If a Quake engine supports colored lights, they'll usually load them automatically.
However, creating non-planar surfaces or changing the lightmap quality on individual surfaces is not supported in this format. If you want to use features such as crouching or proning you have to compile your map with **BSPX** extensions. Other formats also include more features, which can help optimise the network and rendering performance of a level. So use of this format is discouraged by us.
You can totally use it if you're going for a certain aesthetic, just be aware of its limitations. You cannot optimise levels beyond a certain point due to a lack of area-portals which were introduced with Quake II BSP.
### Quake II BSP
A better choice over Quake's standard BSP format. These support area-portals and proper detail brushes can help optimise the level even further.
### Quake III Arena BSP
**The recommended format.** Support for everything Quake II's BSP does, but you can now put a lot of detailed geometry into so called triangle soup, and design your own content volumes (beyond water, lava, slime), and surface flags (make bullets ricochet, or leak water) - make use of curved surfaces, massive maps with terrain and texture blending. Support for different lightmap scales per surface, and alternative vertex-lit levels can also give you tigter controls about lighting performance and visual fidelity.
### VMAP compiled BSP
Our own version of the Quake III Arena BSP format. It supports a bunch of new things.
The compiler doesn't read .shader files from `scripts/` but instead `.mat` files alongside the textures within the textures directory, as well as a custom patch/curve format.
Only use this if you really, really want to use the things we developed. You will have a smoother experience with most other formats right now.
### Other Formats
While the engine can read other formats, such as BSP30 and beyond - please ensure you do have the rights to use the tools in such fashion. For example, for developers coming from the Half-Life SDK you are not allowed to use compilers and versions deriving from the original sources to make maps for Nuclide based projects. You will have to negotiate a license with [Valve](https://www.valvesoftware.com/) or use a free-software tool such as [ericw-tools](https://ericwa.github.io/ericw-tools/).
## Recommended Tools
We don't require you to use WorldSpawn or VMAP. You can use any of the above formats, and whatever editor you like to use to get the job done.
Here's a list of popular editors we've seen people use successfully:
- NetRadiant-Custom
- TrenchBroom
- NetRadiant
- GtkRadiant
- QuArK
- JACK (proprietary)
However we do not provide support for any of them. Please talk to the developers of the respective tools if you're experiencing issues. First ensure that you're able to make levels for your target format.
For example, create an example map for Quake, test it in Quake and then copy it into your Nuclide directory after verifying it works and that the workflow is right for you.
You may need to switch tools if you're not comfortable, and only once you're fully set and familar with the map-making toolchain should you attempt to run the maps in Nuclide.
As map-making is a complicated process, a lot of issues you can run into while making levels for Nuclide, may actually be issues with the toolchain you're using to make the map. So verify it works in the target format's game of choice first.

View file

@ -0,0 +1,93 @@
# Material System(s) {#materials}
**Materials**, also formerly known **Q3 shaders** or wrongly referred to as just **shaders** are scripts that define texture and surface properties.
## History
In the id Tech series of engines, **id Tech 3/Quake III Arena** was the first to introduce such a system, wrongly referred to back then as **shaders**. This was before vertex and fragment shaders were commonplace in the video-game asset pipeline.
![id Tech 3 showcased pulsing tubes and various animated materials. Quake III Arena is property of id Software.](q3a_material.jpg)
They effectively merged the Quake texture-prefix based hacks and **Quake II** .wal surface flags into one plain text format.
Starting with **id Tech 4/Doom III** in 2004, the name of **shader** was changed to **material** to avoid confusion with proper GPU oriented vertex and fragment shaders.
**FTEQW** has since coupled the old 'shader' syntax with proper GPU shaders using the [program](@ref program) material command.
## What is a Material?
Materials are short text scripts that define the properties of a surface as it both appears and functions in the game world.
If you want your sky texture to be replaced with a **skybox**, you will have to write a material definition for that.
If you want to have a surface that looks and acts like water, then you have to write a material for that too. Unlike earlier **id Tech** games no assumption over a surface should be made based on texture names alone.
### When using older BSP formats...
Then you can still use modern materials! While the engine may load a texture from a **bsp** or **wad** file directly, it will still (albeit internally) create a material for it.
When ingame, look at your surface you want to replace with the console variable `r_showshaders` set to `1` - and you will see the path and the contents of the material you're looking at. You can use that information to override rendering for practically any surface, even when using old fileformats.
## Usage
When the engine looks for a texture, it will look for a material file in the filesystem first, then it will attempt to 'make one up' if only an image file is present. A renderable surface will **always** have a material. The question is whether you provide it, or if the engine has to automatically generate one internally.
The file extension for materials in Nuclide is .mat. There are two ways of defining materials:
- A large .shader script file containing multiple materials inside the `<gamedir>/scripts/` folder (not recommended)
- One small .mat file with the same path as the texture. E.g: `models/weapons/handcannon/w_handcannon/w_handcannon.mat` handles `models/weapons/handcannon/w_handcannon/w_handcannon.tga`
A material file consists of a series of surface attributes (global scope) and rendering instructions formatted within braces ("{" and "}"). Below you can see a simple example of syntax and format for a single process, including the VMAP keywords or 'Surface Parameters', which follow the first bracket and a single bracketed 'stage':
```
// Vera Visions Material
{
diffusemap textures/common/lava.tga
vmap_tessSize 64
{
program unlit
blendFunc add
}
}
```
The first line is a simple comment. All the official textures are marked that way.
`diffusemap` defines a texture sampler to associate with the material, it'll also be used by the real-time lights to render an impacted surface, hence why it's defined at a global scope. Other materials may need to be aware of it. The compiler also uses it to compute radiosity.
`vmap_tessSize` will tell the BSP compiler to tesselate the surface in a specific way. This affects the entire surface and not just a single rendering stage, hence why it's defined at a global scope.
We then follow into the territory of defining specific rendering instructions within braces ("{" and "}"), most of the time that's not needed if we're defining a simple, opaque material. However in this case we want to make sure that we have 1 rendering stage that blends additively. Things such as real-time lights and the BSP compiler ignore these additional stages entirely.
`program unlit` will tell it not to be affected by lighting and just use a simple fullbright shader.
`blendFunc add` will now tell the renderer that this surface is no longer opaque and will be blended with whatever equation will result in an additive blend.
[You can read more about those commands in detail right here.](@ref mat_commands)
## Engine generated materials
If no material definition for a surface is present, the engine will create an internal one.
It's generally a primitive material using the internal **defaultwall** shader if it's a world texture, the **defaultskin** texture if it's a model, or a **default2d** if it's a HUD element.
## Q3A style materials, without GLSL
You can support old-style Q3A materials alongside modern shader oriented ones.
```
{
if $programs
program vertexlit
diffusemap "models/weapons/handcannon/w_handcannon.dds"
normalmap "models/weapons/handcannon/w_handcannon_normal.dds"
else
{
map "models/weapons/handcannon/w_handcannon.tga"
rgbGen lightingDiffuse
}
endif
}
```
Here everything inside the **if $programs** block will only ever load if it's capable of handling the GLSL.
So if the player has a card that does not support programmable shaders, the **else** path will take over.

View file

@ -0,0 +1,17 @@
# Material Command List {#mat_commands}
Here is a list of all the commands that can be contained within a material definition file, like a **mat** or a **shader** file.
There are three different kinds of commands:
- Surface Specific
- Stage/Layer Specific
- vmap Specific
Surface specific commands affect the entire surface, or sometimes whole brush-volume it belongs to. Example commands may be @ref surfaceparm.
Stage/Layer specific commands only affect one part of the rendering stage. Generally anything within a sub-block of braces (`{ }`) is a stage. It defines a layer to draw on top of the surface.
Due to how simple most surfaces are, you don't have to define a stage. It is often enough to set @ref program, @ref diffuseMap and you're rendering a surface handled entirely by the GPU.
Some operations, such as [deformVertexes](@ref deformVertexes) or [tcMod](@ref tcMod) are done on the CPU. While you can use those, know that moving that action into a [Shader Program](@ref shaders) is recommended.

View file

@ -0,0 +1,301 @@
# Material System(s) {#materials}
## GoldSrc Material System {#gsmaterials}
In the GoldSrc games "Material" definitions handle what footsteps and what impact sounds are played against each texture in the game-world.
![Generic bullet impact effect in Half-Life. Half-Life belongs to Valve Corporation.](hl_impact.jpg)
So when you walk on dirt, you can hear the difference; or when you shoot wood with a gun it will sound like wood.
**Note:** While Nuclide supports this for legacy BSP files, please define the surface properties inside your [material](@ref mat_commands) using the [**surfaceprop**](@ref surfdata) command.
### Details
Usually, a game in the GoldSrc engine would provide a `sound/materials.txt` file, where each line defines the properties for a single (or a series of) textures by starting with a material id character, followed by whitespace, followed by a name matching pattern.
For example:
`C CONCRETEWALL`
Will give any surface the id **C** if it starts with the name `CONCRETEWALL`.
It will also only compare the length of characters of the name above. So for example if you were to define:
`C CONC`
Then `CONCRETEWALL` would still be marked as concrete, and any other texture that starts with `CONC[...]`.
**Note:** In vanilla Half-Life, the second argument (name) can only be 12 characters long.
When you then walk around your level, the footstep will then be aware of you being on a texture marked with the **C** attribute and play a different step sound. Games are free to define what those material id characters mean - so different games/mods may interpret it differently.
Porting levels can sometimes be a bit more work than it first appears to be at first glance as a result!
### Later Enhancements
#### Community additions
In stock GoldSrc games, the `sound/materials.txt` can be overwritten by a modification but it couldn't be dynamically extended in any way.
This means there was no possibility of map specific materials, and mods could not inherit Half-Life's materials, so mods would always have to manage a nearly duplicate file if they desired custom material definitions.
A few mods tried to remedy this problem, the following below are methods
documented so far:
file named maps/MAPNAME.mat
: Introduced in The Wastes (2003)
file named maps/MAPNAME_materials.txt
: Convention by Andrew Lucas, creator of Trinity SDK, modeled after MAPNAME_details.txt
worldspawn entity key named 'materials_file' with the value `PATH_TO/FILE.txt`
: Introduced in Sven Co-op 5.0
**All these methods are supported by Nuclide**, as one goal is to implement
conventions by not only Valve but the community as well!
#### Nuclide additions
In addition Nuclide has also implemented a way of giving modifications
their own *inheritable* materials file:
`sounds/materials_UNIQUENAME.txt`
The idea here is that any mod or even map pack can include ONLY the textures
used, and no longer will anyone have to manage a near-clone of `sound/materials.txt`.
For repackaging or modding purposes, if you desire to give your map custom
material property definitions, we recommend **The Wastes** its method for individual maps,
while the Nuclide method should be used for **mods** or **map packs**.
**Note:** We recommend only using material text files for GoldSrc related modding
purposes. It is inefficient for modern projects as there are much better
standards already supported in Nuclide.
## Material List
In Nuclide, this is the currently supported list of material IDs:
| Material ID | Material Name |
|-------------|---------------|
| B | Bloody Flesh |
| C | Concrete |
| D | Dirt |
| F | Flesh |
| G | Grate |
| H | Alien |
| K | Snow |
| M | Metal |
| N | Sand |
| O | Foliage |
| P | Computer |
| S | Slosh |
| T | Tile |
| V | Vent |
| W | Wood |
| Y | Glass |
### Game differences
Different games/mods can ship with different material properties.
To make your life easier, you can edit `scripts/surfaceproperties.txt` and define
which Material ID character maps to which [surfaceproperty](@ref surfdata) entry.
This way you can add new materials to existing legacy maps without writing a line of code.
Listed below are definitions for various games and mods. Only the changes and additions are listed since the rest are identical.
### GoldSrc Games/Mods
#### Arrangement
| Material ID | Material Name |
|-------------------|---------------------|
| B | Blue Texture |
| N | Snow |
| R | Red Texture |
| U | Slime |
| X | Yellow Texture |
| Z | Black Texture |
#### Counter-Strike
| Material ID | Material Name |
|-------------------|---------------------|
| N | Snow |
| X | Grass |
*Afraid of Monsters: DC, Natural Selection, and Snow War uses the same definitions.*
#### Cry of Fear
| Material ID | Material Name |
|-------------------|---------------------|
| B | Random Twig Snap |
| H | Paper |
| I | Mud |
| O | Sand |
| P | Snow |
| R | Gravel |
| U | Grass |
| Y | Broken Glass |
| Z | Carpet |
#### Gunman Chronicles
| Material ID | Material Name |
|-------------------|---------------------|
| G | Wood |
| T | Rock |
| V | Sand |
| W | Unknown/Unused? |
#### Firearms
| Material ID | Material Name |
|-------------------|-----------------------------------------|
| B | Sandbag |
| N | Snow |
| U | No impact or decals, just smoke effects |
#### Heart of Evil
| Material ID | Material Name |
|-------------------|---------------------|
| U | Mud |
#### Hostile Intent
| Material ID | Material Name |
|-------------------|---------------------|
| A | Sand |
| E | Foliage |
| N | Snow |
| R | Carpet |
| U | Mud |
| Z | Grass |
#### Household DEATH!
| Material ID | Material Name |
|-------------------|---------------------|
| H | Wood (Creaky) |
| I | Grass |
#### Night at the Office
| Material ID | Material Name |
|-------------------|---------------------|
| T | Carpet |
#### Opposing Force
| Material ID | Material Name |
|-------------------|---------------------|
| O | Snow |
*Science and Industry uses the same definitions as Opposing Force.*
#### Poke646
| Material ID | Material Name |
|-------------------|---------------------|
| M | Metal/Grate |
| T | Wood/Tile |
| G | Carpet/Grass |
#### Wasteland Half-Life
| Material ID | Material Name |
|-------------------|---------------------|
| B | Barrel |
| I | Sand |
| N | Tinroof |
| R | Rust |
| U | Drywall |
*The Wastes uses the same definitions.*
### Source Engine Games/Mods
While Source has materials describing a surface with its own **$surfaceprop** command, the GoldSrc way of describing materials with a 1-character symbol is still used to define which **impact effect** to use.
The **Material ID** is used via the `gamematerial` command inside `scripts/surfaceproperties.txt` entries. In Nuclide that's used for compatibility with the GoldSrc system instead.
![Bullet impact on Plaster](source_plaster.jpg)
![Bullet impact on Wood](source_wood.jpg)
![Bullet impact on Metal](source_metal.jpg)
Be aware that a Source engine game may actually have more surface materials than this, these are *solely the IDs associated with impact effects*.
#### Alien Swarm
| Material ID | Material Name |
|-------------------|---------------------|
| 11 | Steam Pipe |
**Alien Swarm: Reactive Drop uses the same definitions.**
#### Counter-Strike: Global Offensive
| Material ID | Material Name |
|-------------------|---------------------------|
| 11 | Mud |
| 12 | Sand Barrel |
| 13 | Sand Barrel (Penetration) |
| 14 | Metal Shield |
#### Half-Life 2
| Material ID | Material Name |
|-------------------|---------------------|
| A | Antlion |
| B | Flesh (Bloody) |
| H | Flesh (Antlion) |
| K | Snow |
| L | Plastic |
| N | Sand |
| I | Clip |
| O | Foliage |
| X | Fake |
| - | No Decal |
#### Half-Life 2: Episode 2
| Material ID | Material Name |
|-------------------|---------------------|
| E | Antlion Egg Sacks |
| Z | Adviser Shield |
#### Insurgency
| Material ID | Material Name |
|-------------------|---------------------|
| A | Fruit |
*Day of Infamy uses the same definitions.*
#### Left 4 Dead
| Material ID | Material Name |
|-------------------|---------------------|
| J | Grass |
| K | Mud |
| Q | Asphalt |
| R | Brick |
| U | Cardboard |
| 1 | Clay |
| 2 | Plaster |
| 3 | Rock |
| 4 | Rubber |
| 5 | Sheetrock |
| 6 | Cloth |
| 7 | Carpet |
| 8 | Paper |
| 9 | Upholstery |
| 10 | Puddle |
#### Portal 2
| Material ID | Material Name |
|-------------------|---------------------|
| R | Reflective |

View file

@ -1,4 +0,0 @@
# Materials: Commands {#mat_commands}
These are all the important material commands that affect the renderer in some shape or form.
[For material commands that affect the compiling process, look over here.](Documentation/Materials/MatVMap.md)

View file

@ -1,299 +0,0 @@
# "Materials" in GoldSrc
In the GoldSrc games "Material" definitions handle what footsteps and what impact sounds are played against each texture in the game-world.
![Generic bullet impact effect in Half-Life](hl_impact.jpg)
So when you walk on dirt, you can hear the difference; or when you shoot wood with a gun it will sound like wood.
**Note:** While Nuclide supports this for legacy BSP files, please define the surface properties inside your [material](Documentation/Materials/MatOverview.md) using the **surfaceprop** command.
## Details
Usually, a game in the GoldSrc engine would provide a `sound/materials.txt` file, where each line defines the properties for a single (or a series of) textures by starting with a material id character, followed by whitespace, followed by a name matching pattern.
For example:
`C CONCRETEWALL`
Will give any surface the id **C** if it starts with the name `CONCRETEWALL`.
It will also only compare the length of characters of the name above. So for example if you were to define:
`C CONC`
Then `CONCRETEWALL` would still be marked as concrete, and any other texture that starts with `CONC[...]`.
**Note:** In vanilla Half-Life, the second argument (name) can only be 12 characters long.
When you then walk around your level, the footstep will then be aware of you being on a texture marked with the **C** attribute and play a different step sound. Games are free to define what those material id characters mean - so different games/mods may interpret it differently.
Porting levels can sometimes be a bit more work than it first appears to be at first glance as a result!
## Later Enhancements
### Community additions
In stock GoldSrc games, the `sound/materials.txt` can be overwritten by a modification but it couldn't be dynamically extended in any way.
This means there was no possibility of map specific materials, and mods could not inherit Half-Life's materials, so mods would always have to manage a nearly duplicate file if they desired custom material definitions.
A few mods tried to remedy this problem, the following below are methods
documented so far:
file named maps/MAPNAME.mat
: Introduced in The Wastes (2003)
file named maps/MAPNAME_materials.txt
: Convention by Andrew Lucas, creator of Trinity SDK, modeled after MAPNAME_details.txt
worldspawn entity key named 'materials_file' with the value `PATH_TO/FILE.txt`
: Introduced in Sven Co-op 5.0
**All these methods are supported by Nuclide**, as one goal is to implement
conventions by not only Valve but the community as well!
### Nuclide additions
In addition Nuclide has also implemented a way of giving modifications
their own *inheritable* materials file:
`sounds/materials_UNIQUENAME.txt`
The idea here is that any mod or even map pack can include ONLY the textures
used, and no longer will anyone have to manage a near-clone of `sound/materials.txt`.
For repackaging or modding purposes, if you desire to give your map custom
material property definitions, we recommend **The Wastes** its method for individual maps,
while the Nuclide method should be used for **mods** or **map packs**.
**Note:** We recommend only using material text files for GoldSrc related modding
purposes. It is inefficient for modern projects as there are much better
standards already supported in Nuclide.
# Material List
In Nuclide, this is the currently supported list of material IDs:
| Material ID | Material Name |
|-------------|---------------|
| B | Bloody Flesh |
| C | Concrete |
| D | Dirt |
| F | Flesh |
| G | Grate |
| H | Alien |
| K | Snow |
| M | Metal |
| N | Sand |
| O | Foliage |
| P | Computer |
| S | Slosh |
| T | Tile |
| V | Vent |
| W | Wood |
| Y | Glass |
## Game differences
Different games/mods can ship with different material properties.
To make your life easier, you can edit **scripts/surfaceproperties.txt** and define
which Material ID character maps to which [surfaceproperty](Documentation/Surf_data.md) entry.
This way you can add new materials to existing legacy maps without writing a line of code.
Listed below are definitions for various games and mods. Only the changes and additions are listed since the rest are identical.
## GoldSrc Games/Mods
### Arrangement
| Material ID | Material Name |
|-------------------|---------------------|
| B | Blue Texture |
| N | Snow |
| R | Red Texture |
| U | Slime |
| X | Yellow Texture |
| Z | Black Texture |
### Counter-Strike
| Material ID | Material Name |
|-------------------|---------------------|
| N | Snow |
| X | Grass |
*Afraid of Monsters: DC, Natural Selection, and Snow War uses the same definitions.*
### Cry of Fear
| Material ID | Material Name |
|-------------------|---------------------|
| B | Random Twig Snap |
| H | Paper |
| I | Mud |
| O | Sand |
| P | Snow |
| R | Gravel |
| U | Grass |
| Y | Broken Glass |
| Z | Carpet |
### Gunman Chronicles
| Material ID | Material Name |
|-------------------|---------------------|
| G | Wood |
| T | Rock |
| V | Sand |
| W | Unknown/Unused? |
### Firearms
| Material ID | Material Name |
|-------------------|-----------------------------------------|
| B | Sandbag |
| N | Snow |
| U | No impact or decals, just smoke effects |
### Heart of Evil
| Material ID | Material Name |
|-------------------|---------------------|
| U | Mud |
### Hostile Intent
| Material ID | Material Name |
|-------------------|---------------------|
| A | Sand |
| E | Foliage |
| N | Snow |
| R | Carpet |
| U | Mud |
| Z | Grass |
### Household DEATH!
| Material ID | Material Name |
|-------------------|---------------------|
| H | Wood (Creaky) |
| I | Grass |
### Night at the Office
| Material ID | Material Name |
|-------------------|---------------------|
| T | Carpet |
### Opposing Force
| Material ID | Material Name |
|-------------------|---------------------|
| O | Snow |
*Science and Industry uses the same definitions as Opposing Force.*
### Poke646
| Material ID | Material Name |
|-------------------|---------------------|
| M | Metal/Grate |
| T | Wood/Tile |
| G | Carpet/Grass |
### Wasteland Half-Life
| Material ID | Material Name |
|-------------------|---------------------|
| B | Barrel |
| I | Sand |
| N | Tinroof |
| R | Rust |
| U | Drywall |
*The Wastes uses the same definitions.*
## Source Engine Games/Mods
While Source has materials describing a surface with its own **$surfaceprop** command, the GoldSrc way of describing materials with a 1-character symbol is still used to define which **impact effect** to use.
The **Material ID** is used via the `gamematerial` command inside **scripts/surfaceproperties.txt** entries. In Nuclide that's used for compatibility with the GoldSrc system instead.
![Bullet impact on Plaster](source_plaster.jpg)
![Bullet impact on Wood](source_wood.jpg)
![Bullet impact on Metal](source_metal.jpg)
Be aware that a Source engine game may actually have more surface materials than this, these are *solely the IDs associated with impact effects*.
### Alien Swarm
| Material ID | Material Name |
|-------------------|---------------------|
| 11 | Steam Pipe |
**Alien Swarm: Reactive Drop uses the same definitions.**
### Counter-Strike: Global Offensive
| Material ID | Material Name |
|-------------------|---------------------------|
| 11 | Mud |
| 12 | Sand Barrel |
| 13 | Sand Barrel (Penetration) |
| 14 | Metal Shield |
### Half-Life 2
| Material ID | Material Name |
|-------------------|---------------------|
| A | Antlion |
| B | Flesh (Bloody) |
| H | Flesh (Antlion) |
| K | Snow |
| L | Plastic |
| N | Sand |
| I | Clip |
| O | Foliage |
| X | Fake |
| - | No Decal |
### Half-Life 2: Episode 2
| Material ID | Material Name |
|-------------------|---------------------|
| E | Antlion Egg Sacks |
| Z | Adviser Shield |
### Insurgency
| Material ID | Material Name |
|-------------------|---------------------|
| A | Fruit |
*Day of Infamy uses the same definitions.*
### Left 4 Dead
| Material ID | Material Name |
|-------------------|---------------------|
| J | Grass |
| K | Mud |
| Q | Asphalt |
| R | Brick |
| U | Cardboard |
| 1 | Clay |
| 2 | Plaster |
| 3 | Rock |
| 4 | Rubber |
| 5 | Sheetrock |
| 6 | Cloth |
| 7 | Carpet |
| 8 | Paper |
| 9 | Upholstery |
| 10 | Puddle |
### Portal 2
| Material ID | Material Name |
|-------------------|---------------------|
| R | Reflective |

View file

@ -1,93 +0,0 @@
# Materials
**Materials**, also formerly known **Q3 shaders** or wrongly referred to as just **shaders** are scripts that define texture and surface properties.
## History
In the id Tech series of engines, **id Tech 3/Quake III Arena** was the first to introduce such a system, wrongly referred to back then as **shaders**. This was before vertex and fragment shaders were commonplace in the video-game asset pipeline.
![from pulsing tubes to various animated materials in Quake III Arena](q3a_material.jpg)
They effectively merged the Quake texture-prefix hacks and Quake II .wal surface flags into one plain text format.
Starting with **id Tech 4/Doom III** in 2004, the name of **shader** was changed to **material** to avoid confusion with proper GPU oriented vertex and fragment shaders.
**FTEQW** has since coupled the old 'shader' syntax with proper GPU shaders using the [program](Documentation/Materials/commands/program.md) material command.
## What is a Material?
Materials are short text scripts that define the properties of a surface as it both appears and functions in the game world.
If you want your sky texture to be replaced with a **skybox**, you will have to write a material definition for that.
If you want to have a surface that looks and acts like water, then you have to write a material for that too. Unlike earlier **id Tech** games no assumption over a surface should be made based on texture names alone.
### When using older BSP formats...
Then you can still use modern materials! While the engine may load a texture from a **.bsp** or **.wad** file directly, it will still (albeit internally) create a material for it.
When ingame, look at your surface you want to replace with the console variable **r_showshaders** set to **1* - and you will see the path and the contents of the material you're looking at. You can use that information to override rendering for practically any surface, even when using old fileformats.
## Usage
When the engine looks for a texture, it will look for a material file in the file-tree first, then it will attempt to 'make one up' if only an image file is present. A rendereable surface will **always** have a material. The question is whether you provide it, or if the engine has to automatically generate one internally.
The file extension for materials in Nuclide is .mat. There are two ways of defining materials:
- A large .shader script file containing multiple materials inside the **./scripts/** folder (not recommended)
- One small .mat file with the same path as the texture. E.g: **models/weapons/handcannon/w_handcannon/w_handcannon.mat** handles **models/weapons/handcannon/w_handcannon/w_handcannon.tga**
A material file consists of a series of surface attributes (global scope) and rendering instructions formatted within braces ("{" and "}"). Below you can see a simple example of syntax and format for a single process, including the VMAP keywords or 'Surface Parameters', which follow the first bracket and a single bracketed 'stage':
```
// Vera Visions Material
{
diffusemap textures/common/lava.tga
vmap_tessSize 64
{
program unlit
blendFunc add
}
}
```
The first line is a simple comment. All the official textures are marked that way.
`diffusemap` defines a texture sampler to associate with the material, it'll also be used by the real-time lights to render an impacted surface, hence why it's defined at a global scope. Other materials may need to be aware of it. The compiler also uses it to compute radiosity.
`vmap_tessSize` will tell the BSP compiler to tesselate the surface in a specific way. This affects the entire surface and not just a single rendering stage, hence why it's defined at a global scope.
We then follow into the territory of defining specific rendering instructions within braces ("{" and "}"), most of the time that's not needed if we're defining a simple, opaque material. However in this case we want to make sure that we have 1 rendering stage that blends additively. Things such as real-time lights and the BSP compiler ignore these additional stages entirely.
`program unlit` will tell it not to be affected by lighting and just use a simple fullbright shader.
`blendFunc add` will now tell the renderer that this surface is no longer opaque and will be blended with whatever equation will result in an additive blend.
[You can read more about those commands in detail right here.](MatCommands.md)
## Engine generated materials
If no material definition for a surface is present, the engine will create an internal one.
It's generally a primitive material using the internal **defaultwall** shader if it's a world texture, the **defaultskin** texture if it's a model, or a **default2d** if it's a HUD element.
## Q3A style materials, without GLSL
You can support old-style Q3A materials alongside modern shader oriented ones.
```
{
if $programs
program vertexlit
diffusemap "models/weapons/handcannon/w_handcannon.dds"
normalmap "models/weapons/handcannon/w_handcannon_normal.dds"
else
{
map "models/weapons/handcannon/w_handcannon.tga"
rgbGen lightingDiffuse
}
endif
}
```
Here everything inside the **if $programs** block will only ever load if it's capable of handling the GLSL.
So if the player has a card that does not support programmable shaders, the **else** path will take over.

View file

@ -1,58 +0,0 @@
# Materials: Shaders
Shaders are referring to GPU-oriented pieces of a program, performing shading and rendering related functions instead of letting the engine handle it.
In **FTEQW** you can specify a custom GLSL or HLSL shader using the [program](Documentation/Materials/commands/program.md) command inside a [Material](Documentation/Materials/MatOverview.md).
## Example Shader
This is a primitive shader file. It includes the vertex and fragment program.
It will respond to the [diffusemap](Documentation/Materials/commands/diffusemap.md) only, which is loaded
into the **d_f** variable. It can be modified from that point onwards.
The commented out line will turn all of the output red.
Give it a try, or something!
```
//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. =======
//
// Purpose:
//
// Example surface
//==============================================================================
!!ver 110
!!samps diffuse
#include "sys/defs.h"
varying vec2 tex_c;
#ifdef VERTEX_SHADER
void main ()
{
tex_c = v_texcoord; /* get our texture coordinates, which we'll use for the texture2D command */
gl_Position = ftetransform(); /* place vertex into the place FTE wants us to put them at */
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
vec4 d_f = texture2D(s_diffuse, tex_c); /* load the fragment from our diffusemap sample */
// d_f.rgb = vec3(1.0, 0.0, 0.0); /* turns out fragment (aka pixel) red */
gl_FragColor = d_f; /* final pixel output is that of d_f */
}
#endif
```
## Dissecting GLSL shaders
When we pass `program <shadername>` in our Material, the engine will load `glsl/<shadername>.glsl` to handle the material for us.
The shader in question needs to define a `main` function for both a vertex and a fragment shader. That's what the **ifdef**s are for in the above example.
You can not have separate files handle vertex/fragment programs, unlike in **id Tech 4/Doom III**.
At some point in the `main` function, we do have to set `gl_Position` and `gl_FragColor` respectively. Those can not be undefined.

View file

@ -1,4 +0,0 @@
# Materials: VMap Commands {#mat_vmap}
The following commands are alter specific behaviour during the **BSP** compilation process.
These are not respected by the engine, the renderer or the game-logic.

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## alphafunc
# Material Command List {#mat_commands}
## alphafunc {#alphafunc}
### Syntax
**alphaFunc <func>**
**alphaFunc \<func\>**
### Overview
@ -18,12 +20,12 @@ portions of the texture map with corresponding alpha values greater than
zero will be written to the framebuffer. **By default alpha testing is
disabled.**
Both alpha testing and normal [alpha blending](blendfunc.md) can be used to get
Both alpha testing and normal [alpha blending](@ref blendFunc) can be used to get
textures that have see-through parts. The difference is that
**alphaFunc** is an all-or-nothing test, while blending smoothly blends
between opaque and translucent at pixel edges.
Alpha test can also be used with
[depthWrite](depthwrite.md), allowing other
[depthWrite](@ref depthWrite), allowing other
effects to be conditionally layered on top of just the opaque pixels by
setting [depthFunc](depthfunc.md) to equal.
setting [depthFunc](@ref depthFunc) to equal.

View file

@ -0,0 +1,24 @@
# Material Command List {#mat_commands}
## alphagen {#alphaGen}
### Syntax
**alphaGen \<func\>**
### Overview
The alpha channel can be specified like the [rgb channels](@ref rgbGen). If not specified, it
defaults to 1.0.
### Functions
#### portal
This rendering stage keyword is used in conjunction with the
[surfaceparm](@ref surfaceparm) keyword
portal. The function accomplishes the "fade" that causes the scene in
the portal to fade from view. Specifically, it means "Generate alpha
values based on the distance from the viewer to the portal."
Use `alphaGen portal` on the last rendering pass.

View file

@ -1,12 +1,14 @@
# Materials: Commands {#mat_commands}
## blendfunc
# Material Command List {#mat_commands}
## blendFunc {#blendFunc}
![OpenGL blending cheat-sheet](gl_blendmodes.jpg "from zanir.wz.cz/?p=60")
### Syntax
**blendFunc <simplefunc>**
**blendFunc \<simplefunc\>**
**blendFunc <srcBlend> <destBlend>**
**blendFunc \<srcBlend\> \<destBlend\>**
### Overview
@ -15,30 +17,30 @@ graphic layers are to be mixed together.
### Usage
#### Simplified blend functions {#simplified_blend_functions}
### Simplified blend functions
The most common blend functions are set up here as simple commands, and
should be used unless you really know what you are doing.
##### add {#add}
##### add
This is a shorthand command for `blendFunc GL_ONE GL_ONE`. Effects like
fire and energy are additive.
##### filter {#filter}
##### filter
This is a shorthand command that can be substituted for either
`blendFunc GL_DST_COLOR GL_ZERO` or `blendFunc GL_ZERO GL_SRC_COLOR`. A
filter will always result in darker pixels than what is behind it, but
it can also remove color selectively. Lightmaps are filters.
##### blend {#blend}
##### blend
Shorthand for `blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA`. This is
conventional transparency, where part of the background is mixed with
part of the texture.
#### Explicit blend functions {#explicit_blend_functions}
#### Explicit blend functions
Getting a handle on this concept is absolutely key to understanding all
shader manipulation of graphics.
@ -46,7 +48,7 @@ shader manipulation of graphics.
BlendFunc or "Blend Function" is the equation at the core of processing
shader graphics. The formula reads as follows:
` [Source *`<srcBlend>`] + [Destination * `<dstBlend>`]`
`[Source * <srcBlend>] + [Destination * <dstBlend>]`
**Source** is usually the RGB color data in a texture file.
@ -78,7 +80,7 @@ A general rule is that any Source Blend other than **GL_ONE** (or
**GL_SRC_ALPHA** where the alpha channel is entirely white) will cause
the Source to become darker.
##### Source Blend <srcBlend> {#source_blend}
##### Source Blend <srcBlend>
The following values are valid for the Source Blend part of the
equation.
@ -104,7 +106,7 @@ equation.
except that the value in the alpha channel is inverted by
subtracting it from one.(i.e. A=1.0 - SRC.A)
##### Destination Blend <dstBlend> {#destination_blend}
##### Destination Blend <dstBlend>
The following values are valid for the Destination Blend part of the
equation.
@ -127,7 +129,7 @@ equation.
except that the value in the alpha channel is inverted by
subtracting it from one. (i.e. A=1.0 - SRC.A).
##### Doing the Math: The Final Result {#doing_the_math_the_final_result}
##### Doing the Math: The Final Result
The product of the Source side of the equation is added to the product
of the Destination side of the equation. The sum is then placed into the
@ -136,7 +138,7 @@ Ultimately, the equation creates a modified color value that is used by
other functions to define what happens in the texture when it is
displayed in the game world.
#### Default Blend Function {#default_blend_function}
#### Default Blend Function
If no blendFunc is specified then no blending will take place. That's
just a fact of life.

View file

@ -0,0 +1,16 @@
# Material Command List {#mat_commands}
## depthFunc {#depthFunc}
### Syntax
**depthFunc \<func\>**
### Overview
This controls the depth comparison function used while rendering.
The default is **lequal** (Less than or equal to) where any surface that
is at the same depth or closer of an existing surface is drawn. This is
used for textures with transparency or translucency. Under some
circumstances you may wish to use **equal**, e.g. for light-mapped
grates that are alpha tested (it is also used for mirrors).

View file

@ -0,0 +1,15 @@
# Material Command List {#mat_commands}
## depthWrite {#depthWrite}
### Syntax
**depthWrite**
### Overview
By default, writes to the depth buffer when
[depthFunc](@ref depthFunc) passes will happen
for opaque surfaces and not for translucent surfaces.
Blended surfaces can have the depth writes forced with this function.

View file

@ -1,5 +1,7 @@
# Materials: Commands {#mat_commands}
## program
# Material Command List {#mat_commands}
## program {#program}
**program** defines which GLSL/HLSL shader to load for a defined
material. It also accepts arguments that will recompile a shader with
certain permutations. This is kinda ugly,

View file

@ -1,10 +1,12 @@
# Materials: Commands {#mat_commands}
## rgbgen
# Material Command List {#mat_commands}
## rgbGen {#rgbGen}
### Syntax
**rgbGen <func>**
**rgbGen \<func\>**
**rgbGen wave <func> <base> <amp><phase> <freq>**
**rgbGen wave \<func\> \<base\> \<amp\> \<phase\> \<freq\>**
### Overview
@ -13,58 +15,58 @@ Defines what vertex colors are set to for any given surface.
If no rgbGen is specified, either "identityLighting" or"identity" will
be selected, depending on which blend modes are used.
Valid <func> parameters are const, wave, identity, identityLighting,
Valid \<func\> parameters are const, wave, identity, identityLighting,
entity, oneMinusEntity, fromVertex, and lightingDiffuse.
### Functions {#functions}
### Functions
#### const {#const}
#### const
Follow this up with a vector of the color that you'd like the vertex
colors to be set as. An example for green would be:
```
rgbGen const 0.0 1.0 0.0
rgbGen const 0.0 1.0 0.0
```
#### identityLighting {#identitylighting}
#### identityLighting
Colors will be (1.0,1.0,1.0) if running without overbright bits (NT,
linux, windowed modes), or (0.5, 0.5, 0.5) if running with overbright.
Overbright allows a greater color range at the expense of a loss of
precision. Additive and blended stages will get this by default.
#### identity {#identity}
#### identity
Colors are assumed to be all white (1.0,1.0,1.0). All filters stages
(lightmaps, etc) will get this by default.
#### entity {#entity}
#### entity
Colors are grabbed from the entity's .colormod field.
#### oneMinusEntity {#oneminusentity}
#### oneMinusEntity
Colors are grabbed from 1.0 minus the entity's .colormod field.
#### entityLighting {#entitylighting}
#### entityLighting
Introduced by [FTE](FTE), same as entity, but will receive
Introduced by [FTE](https://www.fteqw.org/), same as entity, but will receive
lighting similar to identityLighting on top of it.
#### vertex {#vertex}
#### vertex
Colors are filled in directly by the data from the map or model files.
This is used for blending brushes and patches. It was used at one point
to store primitive lighting, in case the lightmapped rendering path was
to expensive (this is no longer available).
#### oneMinusVertex {#oneminusvertex}
#### oneMinusVertex
As rgbGen vertex, but inverted.
Design Note: This keyword would probably not be used by a level designer
#### lightingDiffuse {#lightingdiffuse}
#### lightingDiffuse
Colors are computed using a standard diffuse lighting equation. It uses
the vertex normals to illuminate the object correctly.
@ -74,7 +76,7 @@ values to be computed for a dynamic model (i.e. non-map object) in the
world using regular in-game lighting. For example, you would specify on
materials for items, characters, weapons, etc.
#### wave <func> <base> <amp><phase> <freq> {#wave}
#### wave <func> <base> <amp><phase> <freq>
Colors are generated using the specified waveform. An affected texture
with become darker and lighter, but will not change hue. Hue stays
@ -82,7 +84,7 @@ constant. Note that the rgb values for color will not go below 0 (black)
or above 1 (white). Valid waveforms are **sin**, **triangle**,
**square**, **sawtooth** and **inversesawtooth**.
##### <func> {#section}
##### <func>
- **Sin**: color flows smoothly through changes.
- **Triangle**: color changes at a constant rate and spends no
@ -96,23 +98,23 @@ or above 1 (white). Valid waveforms are **sin**, **triangle**,
making the ascent immediate (like a square wave) and the decay fall
off like a triangle wave.
##### <base> {#section_1}
##### <base>
Baseline value. The initial RGB formula of a color (normalized).
##### <amp> {#section_2}
##### <amp>
Amplitude. This is the degree of change from the baseline value. In some
cases you will want values outside the 0.0 to 1.0 range, but it will
induce clamping (holding at the maximum or minimum value for a time
period) instead of continuous change.
##### <phase> {#section_3}
##### <phase>
See the explanation for phase under the waveforms heading of Key
Concepts.
##### <freq> {#section_4}
##### <freq>
Frequency. This is a value (NOT normalized) that indicates peaks per
second.

View file

@ -0,0 +1,26 @@
# Material Command List {#mat_commands}
## tcGen {#tcGen}
### Syntax
**tcGen \<coordinate source\>**
### Overview
Specifies how texture coordinates are generated and where they come
from. Valid functions are **base**, **lightmap** and **environment**.
### Sources
#### base
Base texture coordinates from the original art.
#### lightmap
Lightmap texture coordinates.
#### environment
Make this object environment mapped.

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## tcmod
# Material Command List {#mat_commands}
## tcMod {#tcMod}
### Syntax
**tcMod <func> [...]**
**tcMod \<func\> [...]**
### Overview
@ -22,15 +24,15 @@ Texture coordinates are modified in the order in which **tcMods** are
specified. In otherwords, if you see:
```
 tcMod scale 0.5 0.5
 tcMod scroll 1 1
tcMod scale 0.5 0.5
tcMod scroll 1 1
```
Then the texture coordinates will be **scaled** then **scrolled**.
### Functions {#functions}
### Functions
#### rotate <degrees per per second> {#rotate}
#### rotate <degrees per per second>
This keyword causes the texture coordinates to rotate. The value is
expressed in degrees rotated each second. A positive value means
@ -41,7 +43,7 @@ center point of the texture map, so you are rotating a texture with a
single repetition, be careful to center it on the brush (unless
off-center rotation is desired).
#### scale <sScale> <tScale> {#scale}
#### scale <sScale> <tScale>
Resizes (enlarges or shrinks) the texture coordinates by multiplying
them against the given factors of <sScale> and &lt;tScale). The values
@ -58,7 +60,7 @@ Example: `tcMod scale 0.5 2` would cause the texture to repeat twice
along its width, but expand to twice its height (in which case half of
the texture would be seen in the same area as the original)
#### scroll <sSpeed> <tSpeed> {#scroll}
#### scroll <sSpeed> <tSpeed>
Scrolls the texture coordinates with the given speeds. The values "s"
and "t" conform to the "x" and "y" values (respectively) as they are
@ -75,7 +77,7 @@ texture each second of travel.
**This should be the LAST tcMod in a stage.** Otherwise there maybe
popping or snapping visual effects in some materials.
#### stretch <func> <base> <amplitude> <phase> <frequency> {#stretch}
#### stretch <func> <base> <amplitude> <phase> <frequency>
Stretches the texture coordinates with the given function. Stretching is
defined as stretching the texture coordinate away from the center of the
@ -107,7 +109,7 @@ keyword.
wave.
- **Inversesawtooth**: this is the reverse of the sawtooth wave.
#### transform <m00> <m01> <m10> <m11> <t0> <t1> {#transform}
#### transform <m00> <m01> <m10> <m11> <t0> <t1>
Transforms each texture coordinate as follows:
@ -115,7 +117,7 @@ S' = s \* m00 + t \* m10 + t0 T' = s \* m01 + t \* m11 + t1
This is for use by programmers.
#### turb <base> <amplitude> <phase> <freq> {#turb}
#### turb <base> <amplitude> <phase> <freq>
Applies turbulence to the texture coordinate. Turbulence is a back and
forth churning and swirling effect on the texture.

View file

@ -0,0 +1,76 @@
# Material Command List {#mat_commands}
## bemode {#bemode}
### Syntax
**bemode \<mode\>**
### Overview
Filters which back end rendering features are drawn on top of the material.
While you're not encouraged to be overriding this value, it is sometimes necessary.
### Modes {#bemode_sides}
These are the different modes that we can specify.
#### rtlight {#bemode_rtlight}
All light types will be drawn onto this surface.
#### rtlight_only {#bemode_rtlight_only}
Dynamic lights only.
#### rtlight_smap {#bemode_rtlight_smap}
Shadowmaps only.
#### rtlight_spot {#bemode_rtlight_spot}
Spotlights only.
#### rtlight_cube {#bemode_rtlight_cube}
Cubemap lights only.
#### rtlight_cube_smap {#bemode_rtlight_cube_smap}
Cubemap lights and shadowmaps only.
#### rtlight_cube_spot {#bemode_rtlight_cube_spot}
Cubemap lights and spotlights only.
#### rtlight_spot_smap {#bemode_rtlight_spot_smap}
Spot lights and shadowmaps only.
#### rtlight_cube_spot_smap {#bemode_rtlight_cube_spot_smap}
Cubemap lights, spot lights and shadowmaps only.
#### crepuscular {#bemode_crepuscular}
For skies that might cast rays.
Those are rendered to a frame buffer object (with everything else being [depthdark](@ref bemode_depthdark)) and is then applied to the screen as a post-processing effect.
#### depthonly {#bemode_depthonly}
Used mainly by shadow maps.
#### depthdark {#bemode_depthdark}
Black depth passes only.
Used to draw a black world, when `r_shadow_realtime_world_lightmaps` is `0` for example.
#### gbuffer {#bemode_gbuffer}
#### prelight {#bemode_prelight}
Deferred lighting only.
#### fog {#bemode_fog}
Fog layer only.

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## cull
# Material Command List {#mat_commands}
## cull {#cull}
### Syntax
**cull <side>**
**cull \<side\>**
### Overview
@ -18,21 +20,21 @@ is not specified. However for items that should be inverted then the
value back should be used. To disable culling, the value disable or none
should be used. Only one cull instruction can be set for the material.
### Sides {#sides}
### Sides {#cull_sides}
#### front {#front}
#### front {#cull_front}
**This is the default value.** The front or "outside" of the polygon is
not drawn in the world. It is used if the keyword `"cull "` appears in
the content instructions without a <side> value or if the keyword cull
the content instructions without a \<side\> value or if the keyword cull
does not appear at all in the shader.
#### back {#back}
#### back {#cull_back}
Cull back removes the back or "inside" of a polygon from being drawn in
the world.
#### none {#none}
#### none {#cull_none}
Neither side of the polygon is removed. Both sides are drawn in the
game. Very useful for making panels or barriers that have no depth, such

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## deformvertexes
# Material Command List {#mat_commands}
## deformVertexes {#deformVertexes}
### Syntax
**deformVertexes <func>**
**deformVertexes \<func\>**
### Overview
@ -12,9 +14,9 @@ passes. You can stack multiple deformVertexes commands to modify
positions in more complex ways, making an object move in two dimensions,
for instance.
### Functions {#functions}
### Functions
#### wave <siv> <func> <base> <amplitude> <phase> <freq> {#wave}
#### wave <siv> <func> <base> <amplitude> <phase> <freq>
Designed for water surfaces, modifying the values differently at each
point.
@ -23,10 +25,10 @@ It accepts the standard **wave** functions of the type: **sin**,
**triangle**, **square**, **sawtooth** or **inversesawtooth**.
The "div" parameter is used to control the wave "spread" - a value equal
to the [tessSize](vmap_tesssize.md) of the
to the [tessSize](@ref vmap_tesssize) of the
surface is a good default value.
#### normal <siv> <func> <base> <amplitude> <frequency> {#normal_amplitude}
#### normal <siv> <func> <base> <amplitude> <frequency>
This deformation affects the normals of a vertex without actually moving
it, which will effect later material options like lighting and
@ -38,12 +40,12 @@ in any of their calculations, there will be no visible effect.
that have been done with it: A small fluttering bat, falling leaves,
rain, flags.
#### bulge <bulgeWidth> <bulgeHeight> <bulgeSpeed> {#bulge}
#### bulge <bulgeWidth> <bulgeHeight> <bulgeSpeed>
This forces a bulge to move along the given s and t directions. Designed
for use on curved pipes.
#### move <x> <y> <z> <func> <base> <amplitude> <phase> <freq> {#move}
#### move <x> <y> <z> <func> <base> <amplitude> <phase> <freq>
This keyword is used to make a brush, curve patch or model appear to
move together as a unit. The **x** **y** and **z** values are the
@ -66,7 +68,7 @@ actually change position, it only appears to.
materials, all must have matching deformVertexes move values or **the
object will appear to tear itself apart!**
#### autosprite {#autosprite}
#### autosprite
This function can be used to make any given triangle quad (pair of
triangles that form a square rectangle) automatically behave like a
@ -81,7 +83,7 @@ texture with this material keyword must be square.
**Design Note**: This is best used on objects that would appear the same
regardless of viewing angle. An example might be a glowing light flare.
#### autosprite2 {#autosprite2}
#### autosprite2
Is a slightly modified "sprite" that only rotates around the middle of
its longest axis.
@ -89,11 +91,11 @@ its longest axis.
This allows you to make a pillar of fire that you can walk around, or an
energy beam stretched across the room.
### Notes {#notes}
### Notes
Specific parameter definitions for deform keywords:
#### <siv> {#section}
#### <siv>
This is roughly defined as the size of the waves that occur. It is
measured in game units. Smaller values create agreater density of
@ -101,12 +103,12 @@ smaller wave forms occurring in a given area. Larger values create a
lesser density of waves, or otherwise put, the appearance of larger
waves. To look correct this value should closely correspond to the value
(in pixels) set for
[tessSize](vmap_tesssize.md) of the texture.
[tessSize](@ref vmap_tesssize) of the texture.
A value of 100.0 is a good default value (which means your
[tessSize](vmap_tesssize.md) should be close
[tessSize](@ref vmap_tesssize) should be close
to that for things tolook "wavelike").
#### <func> {#section_1}
#### <func>
This is the type of wave form being created. **sin** stands for sine
wave, a regular smoothly flowing wave. **triangle** is a wave with a
@ -116,20 +118,20 @@ frequency with no in between. The **sawtooth** wave has the ascent of a
triangle wave, but has the decay cut off sharply like a square wave. An
**inversesawtooth** wave reverses this.
#### <base> {#section_2}
#### <base>
This is the distance, in game units that the apparent surface of the
texture is displaced from the actual surface of the brush as placed in
the editor. A positive value appears above the brush surface. A negative
value appears below the brush surface.
#### <amplitude> {#section_3}
#### <amplitude>
The distance that the deformation moves away from the base value. See
Wave Forms in the introduction for a description of amplitude. <phase>
SeeWave Forms in the introduction for a description of phase)
#### <frequency> {#section_4}
#### <frequency>
See Wave Forms in the introduction for a description of frequency)

View file

@ -0,0 +1,16 @@
# Material Command List {#mat_commands}
## diffuseMap {#diffuseMap}
### Syntax
**diffuseMap \<texturepath/texturename\>**
### Overview
Specifies the default texture asset to use on the diffuse/albedo pass of
the material. This is the base texture in most cases. Some special
materials used for special effects and the like might not have one.
However surfaces such as floors, walls etc. certainly do. It will affect
which texture is used to get color information from for lighting passes,
etc.

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## fogparms
# Material Command List {#mat_commands}
## fogParms {#fogParms}
### Syntax
**fogParms <red value> <green value> <blue value> <distance to opaque>**
**fogParms \<red value\> \<green value\> \<blue value\> \<distance to opaque\>**
### Overview

View file

@ -0,0 +1,14 @@
# Material Command List {#mat_commands}
## fte_clutter {#fte_clutter}
### Syntax
**fte_clutter \<model\> \<spacing\> \<scale min\> \<scale max\> \<z offset\>
\<angle min\> \<angle max\>**
### Overview
Similar to [vmap_surfaceModel (vmap_surfacemodel.md), however
it'll place models at runtime. The density can be controlled via the
cvar `r_clutter_density`.

View file

@ -0,0 +1,17 @@
# Material Command List {#mat_commands}
## fullbrightMap {#fullbrightMap}
### Syntax
**fullbrightMap \<texturepath/texturename\>**
### Overview
The texture is essentially a fullbright overlay on top of the
diffuse/albedomap.
Not all [Shaders](@ref shaders) support them. In some, like the
[unlit](@ref unlit) shader, the
[diffusemap](@ref diffusemap) is always
fullbright.

View file

@ -1,12 +1,14 @@
# Materials: Commands {#mat_commands}
## nomipmaps
# Material Command List {#mat_commands}
## noMipmaps {#noMipmaps}
### Syntax
**noMipmaps**
### Overview
This implies [noPicMip](nopicmip.md), but
This implies [noPicMip](@ref noPicMip), but
also prevents the generation of any lower resolution mipmaps for use by
the 3d card. This will cause the texture to alias when it gets smaller,
but there are some cases where you would rather have this than a blurry

View file

@ -0,0 +1,14 @@
# Material Command List {#mat_commands}
## noPicMip {#noPicMip}
### Syntax
**noPicMip**
### Overview
This causes the texture to ignore user-set values for the gl_picmip cvar
command. The image will always be high resolution. Example: Used to keep
images and text in the heads up display from blurring when user
optimizes the game graphics.

View file

@ -0,0 +1,19 @@
# Material Command List {#mat_commands}
## normalMap {#normalMap}
### Syntax
**normalMap \<texturepath/texturename\>**
### Overview
Specifies the default texture to use for any normalmap operations. This
depends heavily on which [GLSL program](@ref shaders) is used
inside the later stages. The dynamic lights will use this to determine
height information for light and shadows. So sometimes you want to skip
setting this.
### Creating normal maps to use with this command {#creating_normal_maps_to_use_with_this_command}
Check out our [Normal mapping guide](@ref normal_mapping_guide).

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## polygonoffset
# Material Command List {#mat_commands}
## polygonOffset {#polygonOffset}
### Syntax
**polygonOffset <value>**
**polygonOffset \<value\>**
### Overview

View file

@ -0,0 +1,14 @@
# Material Command List {#mat_commands}
## portal {#mat_portal}
### Syntax
**portal**
### Overview
Specifies that this texture is the surface for a portal or mirror. In
the game map, a portal entity must be placed directly in front of the
texture (within 64 game units). All this does is set "sort portal", so
it isn't needed if you specify that explicitly.

View file

@ -0,0 +1,12 @@
# Material Command List {#mat_commands}
## reflectCube {#reflectCube}
### Syntax
**reflectCube \<texturepath/cubemapname\>**
### Overview
Specifies which cubemap to use on this material. By default, the engine
will pass the nearest in-world cubemap instead.

View file

@ -0,0 +1,17 @@
# Material Command List {#mat_commands}
## reflectMask {#reflectMask}
### Syntax
**reflectMask \<texturepath/texturename\>**
### Overview
Defines a texture that specifies which parts of a material will reveal a
reflective material, such as a
[cubemap](@ref reflectcube). This applies to
standard FTEQW. In Nuclide the reflectmask is currently unused with the
included shaders. If you want to apply reflectivity to your materials,
use the alpha channel of your
[normalmap](normalmap.md) instead.

View file

@ -0,0 +1,56 @@
# Material Command List {#mat_commands}
## skyParms {#skyParms}
### Overview
**skyParms \<farbox\> \<cloudheight\> \<nearbox\>**
Specifies how to use the surface as a sky, including an optional far box
(stars, moon, etc), optional cloud layers with any shader attributes,
and an optional near box (mountains in front of the clouds, etc). Some
of the VMAP specific commands use this as a reference as to what skybox
to use for color, intensity etc.
The renderer will take it into account only if you do not supply any
Stages in the material.
**farbox**: Specifies a set of files to use as an environment box
behind all cloudlayers. Specify "-" for no farbox, or a file base name.
A base name of "env/test" would look for files "env/test_rt.tga",
"env/test_lf.tga", "env/test_ft.tga", "env/test_bk.tga",
"env/test_up.tga", "env/test_dn.tga" to use as the right / left / front
/ back / up / down sides.
**cloudheight**: controls apparent curvature of the cloud layers -
lower numbers mean more curvature (and thus more distortion at the
horizons). Higher height values create "flatter" skies with less horizon
distortion. Think of height as the radius of a sphere on which the
clouds are mapped. Good ranges are 64 to 256. The default value is 128.
**nearbox**: Specified as farbox, to be alpha blended ontop of the
clouds. This has not be tested in a long time, so it probably doesn't
actually work. Set to "-" to ignore.
### Example Sky Material {#example_sky_material}
```
// Vera Visions Material
{
qer_editorImage textures/skies/dune.tga
skyParms textures/skies/dune/bg 256 -
noPicMip
noMipmaps
surfaceParm sky
surfaceParm noimpact
surfaceParm nolightmap
surfaceParm nodlight
{
program skybox
map $cube:textures/skies/dune/bg
map textures/skies/clouds/dunecloud.tga
map textures/skies/clouds/dunecloud_layer.tga
}
}
```

View file

@ -1,8 +1,10 @@
# Materials: Commands {#mat_commands}
## sort
# Material Command List {#mat_commands}
## sort {#sort}
### Syntax
**sort <value>**
**sort \<value\>**
### Overview
@ -33,7 +35,7 @@ the following list (listed in order of mostly ascending priority):
optimization on some cards. This currently has the wrong value for
this purpose, so it doesn't do much of anything.
- **opaque**: This surface is opaque (rarely needed since this is the
default with noblendfunc)
default with noblendFunc)
- **decal**: Blend it like a decal. Ones affected by light, or
something.
- **seethrough**: Not sure what to call this, beyond repeating its
@ -44,7 +46,7 @@ the following list (listed in order of mostly ascending priority):
- **underwater**: Draw behind normal transparent surfaces.
- **blend**: Draw like a blendFunc blend transparent surface.
- **additive**: normal transparent surface (default for shaders with
blendfuncs)
blendFuncs)
- **nearest**: this shader should always sort closest to the viewer,
e.g. muzzle flashes and blend blobs

View file

@ -0,0 +1,14 @@
# Material Command List {#mat_commands}
## specularMap {#specularMap}
### Syntax
**specularMap \<texturepath/texturename\>**
### Overview
Can set the specularity of the surface in relation to dlights.
Specularity is the intensity of the light reflecting off the surface. In
special cases some [GLSL programs](@ref shaders) might use the
texture it for other purposes, too.

View file

@ -1,5 +1,7 @@
# Materials: Commands {#mat_commands}
## surfaceparm
# Material Command List {#mat_commands}
## surfaceparm {#surfaceparm}
### Overview
The surfaceparm keyword is not only read by the VMAP compiler, but also
@ -223,7 +225,7 @@ addition of an rgbGen identity keyword in that stage.
Light will pass through this surface, but only if either alphashadow or
lightfilter are applied. Tells VMAP that pre-computed visibility should
not be blocked by this surface. Generally, any materials that have
blendfuncs should be marked as surfaceparm trans.
blendFuncs should be marked as surfaceparm trans.
### Material Related Keywords {#material_related_keywords}

View file

@ -0,0 +1,23 @@
# Material Command List {#mat_commands}
## vmap_backmaterial
### Syntax
**vmap_backMaterial \<material\>**
### Overview
This allows a brush surface to use a different material when you are
inside it looking out.
By way of example, this would allow a water brush (or other) surfaces to
have a different sort order or appearance when seen from the inside.
**vmap_backMaterial** only works on brush faces. For this reason, it is
often deprecated in favor of using
[vmap_cloneMaterial](@ref vmap_cloneMaterial)
where the target material contains
[vmap_invert](@ref vmap_invert).
It can still be useful as a kind of shorthand.

View file

@ -0,0 +1,16 @@
# Material Command List {#mat_commands}
## vmap_backsplash
### Syntax
**vmap_backsplash \<percent\> \<distance\>**
### Overview
Controls the percentage of [surfacelight](@ref vmap_surfaceLight) backsplash (how
much light the emitting surface hits), as well as the distant away from
the surface of which it is cast. This is really tricky to get right in
tight areas, so put time aside to experiment.
**The default backsplash amount is 5%, and the default distance is about
16 units.**

View file

@ -0,0 +1,15 @@
# Material Command List {#mat_commands}
## vmap_basematerial
### Syntax
**vmap_baseMaterial \<material\>**
### Overview
Copies the vmap_ and surfaceparm commands from the specified material into
this one.
However, if you want to copy the appearance and only specify
compiler-specific modifications, use
[vmap_remapMaterial](@ref vmap_remapMaterial).

View file

@ -0,0 +1,11 @@
# Material Command List {#mat_commands}
## vmap_bounce
### Syntax
**vmap_bounce \<scale\>**
### Overview
Specifies the fraction of light to re-emit during a bounce pass on this
surface.

View file

@ -0,0 +1,13 @@
# Material Command List {#mat_commands}
## vmap_clonematerial
### Syntax
**vmap_cloneMaterial \<material\>**
### Overview
A material with this directive will inherit the target material's
properties and appearance. **Be careful, this can lead to an infinite
loop if a cloning material references another cloning material or
itself.**

View file

@ -0,0 +1,16 @@
# Material Command List {#mat_commands}
## vmap_invert
### Syntax
**vmap_invert**
### Overview
Inverts a surface normal. Works on brush faces, models and patches. Used
in celshading to achieve the inverted backfacing hull.
Can be used with a material that is targeted by
[vmap_cloneMaterial](@ref vmap_cloneMaterial)
for something similar to
[vmap_backMaterial](@ref vmap_backMaterial).

View file

@ -1,8 +1,9 @@
# Materials: VMap Commands {#mat_vmap}
# Material Command List {#mat_commands}
## vmap_lightimage
### Syntax
**vmap_lightImage <texturepath>**
**vmap_lightImage \<texturepath\>**
### Overview

View file

@ -0,0 +1,31 @@
# Material Command List {#mat_commands}
## vmap_lightmapfilterradius
### Syntax
**vmap_lightmapFilterRadius \<lightmap filter radius\>
\<light filter radius\>**
### Overview
This is usually used on [light emittingmaterials](@ref vmap_surfaceLight) to
approximate finer subdivided lighting. It adds a gaussian blur effect to
the lightmaps of either the material itself, or the surfaces affected by
the material, or both. The values for **\<lightmap filter radius\>** and
**\<light filter radius\>** are measured in world units of filtering
(blurring) of lightmap data cast by any light sources.
**\<lightmap filter radius\>** Amount of blur set for the material itself
to approximate for the [surface lights](vmap_surfaceLight) finer
subdivided lighting. It should be set to 0 for sky materials since they
don't have lightmaps.
**\<light filter radius\>**: Amount of blur set for other surfaces
affected by this material's emitted light. It should be set just high
enough to eliminate the "stadium shadow" effect sometimes produced by
[light_environment](@ref light_environment) or to smooth out the
lighting on [surface lights](@ref vmap_surfaceLight).
[vmap_lightmapFilterRadius](@ref vmap_lightmapFilterRadius)
should be placed before any light related material directives that you
want it to affect.

View file

@ -1,4 +1,5 @@
# Materials: VMap Commands {#mat_vmap}
# Material Command List {#mat_commands}
## vmap_lightmapmergable
### Syntax

View file

@ -0,0 +1,14 @@
# Material Command List {#mat_commands}
## vmap_lightmapsampleoffset
### Syntax
**vmap_lightmapSampleOffset \<float\>**
### Overview
Takes a single parameter, defaulting to 1.0, which specifies how many
units off a surface should the compiler sample lighting from. Use larger
values (2.0-8.0) if you're getting ugly splotches on lightmapped
terrain. Try to use filtering to solve splotches if possible, leaving
vmap_lightmapSampleOffset as a last resort.

View file

@ -1,8 +1,9 @@
# Materials: VMap Commands {#mat_vmap}
# Material Command List {#mat_commands}
## vmap_lightmapsamplesize
### Syntax
**vmap_lightmapSampleSize <int>**
**vmap_lightmapSampleSize \<int\>**
### Overview

View file

@ -0,0 +1,12 @@
# Material Command List {#mat_commands}
## vmap_lightrgb
### Syntax
**vmap_lightRGB \<red color\> \<green color\> \<blue color\>**
### Overview
Alternative to [vmap_lightImage (MaterialCommand)](@ref vmap_lightImage) and the
automatic way of figuring out which light color a specified surface
emits.

View file

@ -0,0 +1,15 @@
# Material Command List {#mat_commands}
## vmap_lightsubdivide
### Syntax
**q3map_lightSubdivide \<units\>**
### Overview
Used on surface lights (see [vmap_surfaceLight (Material Command)](@ref vmap_surfaceLight)). Controls
the distance between surface generated light sources for uniform
lighting. It defaults to 120 game units, but can be made larger or
smaller as needed (for light surfaces at the bottom of cracks, for
example). This can be a dominant factor in processing time for lightmap
generation.

View file

@ -0,0 +1,11 @@
# Material Command List {#mat_commands}
## vmap_nodirty
### Syntax
**vmap_nodirty**
### Overview
This surface is not affected by dirt-mapping. The compiler baked variant
of ambient occlusion.

View file

@ -0,0 +1,12 @@
# Material Command List {#mat_commands}
## vmap_offset
### Syntax
**vmap_offset \<float\>**
### Overview
Offsets a surface along the vertex normals by N.N units. Used in
celshading for those black edges. This is the sort-of the compiler
version of [polygonOffset](@ref polygonOffset)

View file

@ -0,0 +1,21 @@
# Material Command List {#mat_commands}
## vmap_remapmaterial
### Syntax
**vmap_remapMaterial \<material\>**
### Overview
Allows the material to later become known as the specified material.
These materials should not contain anything but compiler-specific
keywords.
For example, if you want a material that is exactly like the
specified **vmap_remapMaterial** in appearance, but with a
specific **vmap_** instruction or surfaceparm characteristics, use this command.
However, if you want want just a material's vmap_/surfaceparm
properties, use
[vmap_baseMaterial](@ref vmap_baseMaterial).

Some files were not shown because too many files have changed in this diff Show more