Files

16 KiB
Raw Permalink Blame History

feedc0de Coop Addon

This repository is a complete Garry's Mod addon. It contains the feedc0de_coop gamemode under gamemodes/ and reusable Lua entities under lua/entities/. Installing the repository as garrysmod/addons/feedc0de_coop enables both the campaign gamemode and the standalone friendly scanner.

Persistent progression and rewards shop

Players earn Lifetime Score and spendable Credits for eligible monster kills; harder enemies award more. Lifetime Score determines rank and never decreases. Each awarded kill creates its own HUD line with the enemy name and Score gained; rapid and simultaneous kills stack independently, remain for one second, and then fade out. Every ten connected minutes also awards five Credits. Shop purchases deduct Credits only. Changes remain in memory during active play and are written to Garry's Mod's SQLite database at garrysmod/sv.db only when the server is empty or shutting down, avoiding gameplay stalls from synchronous SQLite I/O.

Dying deducts up to five Credits, stopping at zero. It never deducts Lifetime Score and therefore cannot lower a player's rank.

Player controls:

  • F3, chat !shop, or client console coop_shop: open the rewards shop
  • F3 Players: view the all-time rankings; right-click or double-click a row to open that player's Steam profile
  • Chat !points: print personal Score, Credits, rank, and total playtime
  • Chat !musicmute or client console coop_music_mute: toggle purchased server music locally
  • Client console coop_music_volume 0.0 through coop_music_volume 1.0: set music volume
  • With Hoverpack enabled, jump normally and continue holding Space to hover
  • With Grappling Hook enabled, hold Use + Space while aiming at solid world geometry; release either key to detach
  • !health, !suit, !ammo, !allguns, !boost, !cloak, and !godmode: buy the matching consumable without opening F3
  • !grapple, !bhop, !speed, !fisheye, and !beep: buy or toggle the matching persistent Behaviour
  • !cp, !go, and !ucp: save, return to, or clear a per-map checkpoint
  • Hold TAB: compare connected players' Lifetime Scores, ranks, and total playtime

End-of-map voting

Finishing a mission, reaching the successful !skip threshold, or spending 60 minutes on one map opens the same server-authoritative map vote for every human player. The responsive Derma window offers eight randomly sampled installed co-op maps by default, uses a scrollable card grid on smaller displays, shows live vote counts, and highlights both the local player's choice and the result. Players may change their choice until the vote resolves. It lasts at most 30 seconds and resolves immediately once every connected human has voted.

A map with more than half of submitted votes wins. Without a strict majority, the server chooses uniformly among the maps that received at least one vote. If nobody votes, it chooses uniformly among all displayed choices. When the server is empty, the 60-minute limit skips the UI and changes immediately to a random eligible installed map so the idle server continues rotating.

The old !nextmap and !votenext chat voting commands and automatic nextlevel selection are intentionally removed. !skip remains the way to request an early end to the current mission. Configuration is available through these archived server ConVars:

  • gc_mapvoteduration (default 30, clamped to 5–120 seconds)
  • gc_mapvotechoices (default 8, clamped to 2–12 maps)
  • gc_mapskipvoteratio (default 0.6)
  • gc_mapmaxtime (default 3600; 0 disables the safety limit)
  • gc_mapchangedelay (default 8, applied after an online vote result)
  • gc_mapvotepreviewurl (fallback HTTPS directory for <mapname>.jpg)

The loading-screen sidecar automatically scans the server's mounted Workshop GMA cache and associates each contained BSP with its Workshop item. If the GMA contains maps/thumb/<exact_map_name>.png, the sidecar serves that image to the vote UI directly. Otherwise it resolves and proxies the Workshop item's Steam preview icon. This also covers newly added third-party map items without a manually maintained map-to-Workshop table, and clients do not subscribe to or download all displayed map addons. The scan runs in the background at startup and refreshes every five minutes.

Continue putting maps/thumb/<exact_map_name>.png inside each GMA so the standard single-player map browser also has a preview, and put maps/graphs/<exact_map_name>.ain there when that map has a node graph. A JPEG under the server's garrysmod/map-previews/ directory remains an optional highest-priority override. gamemode/workshop_maps.lua is reserved only for unusual packages that cannot be identified from the normal Workshop cache layout; it is empty by default.

Managed cooperative bots also show a score, rank, and increasing playtime in the TAB scoreboard. Their score uses the same class-weighted monster rewards as a human player's score, but both values are session-only and kept exclusively in memory. Bots are never inserted into SQLite and therefore never appear in the loading-page high scores or the F3 Players list.

Bots use Steam-style handles, a randomly selected player model, and a 50% chance of a randomly selected visible trail from the shop catalogue, plus a randomized in-memory score/playtime offset when they join. They may very rarely play Trolololo through the normal server music path: the check is once per minute at a 1% chance and it has a shared 30-minute minimum interval.

The shop contains persistent Half-Life 2 player models and permanent bonus weapon unlocks. Only one bonus weapon is equipped at a time. It also contains a Music category. Buying a song unlocks it permanently; selecting Play broadcasts it to all connected players. One song can play at a time, with a short cooldown afterward. Each player can mute or adjust the music locally.

The permanent weapon catalogue contains all thirteen spawnable weapons from the gamemode's CO-OP Q-menu category: Glock, P228, USP, Five-Seven, MAC-10, MP5, Pump Shotgun, FAMAS, AK-47, M4A1, Desert Eagle, Automatic Shotgun, and M249. The Workshop novelty weapons are Nyan Gun, Lightsaber, HAAAX! SWEP, Popcorn Spammable, Orbital Friendship Cannon, and Sexyness (2-bit). They are permanent unlocks at their higher prices.

Music entries may set spatial = true plus minimumDistance and maximumDistance. Spatial music follows the buyer's character while they move and fades over distance. Supply spatial audio as 44.1 kHz mono MP3 or WAV for reliable in-game positioning.

The Behaviours category contains persistent, toggleable player abilities. The Hoverpack costs 500 Credits by default and is enabled immediately after buying it. A short Space press remains a normal jump; holding Space for 0.3 seconds in the air maintains altitude and rises slowly. Releasing Space stops thrust and restores normal gravity. Pressing and holding Space again can restart thrust while still airborne. Thrust consumes the standard AUX power meter and stops at zero. After a 1.25-second pause with Space released, AUX recharges while waiting and recharges faster while walking; active sprinting does not receive the extra hoverpack recharge. Its built-in looping thruster sound follows the player and is audible to nearby players.

The Grappling Hook is a separate permanent Behaviour. It traces the solid point under the crosshair, steadily shortens an invisible tether, and applies a smooth speed-capped pull so the player can swing. Clients render the tether as a softly sagging electrical arc. It can be enabled together with Hoverpack: plain Space hovers, Use + Space grapples, and holding both actions lets their forces coexist. Both consume the same AUX reserve, with their drain added while used together.

Other Behaviours provide automatic bunny hopping, a 25% movement boost, wide-angle vision, a pulsing teammate beacon, direct health/suit/ammunition refills, a standard Half-Life 2 arsenal, a three-minute emergency bundle, and a one-minute visual cloak. Consumables are charged per activation; the remaining abilities are bought once and can then be toggled.

God Mode is a non-permanent Behaviour purchase. Each activation costs 1,000 Credits by default and immediately grants 90 seconds of server-enforced damage immunity. It creates no ownership record. Attempting to activate it while it is already running reports the remaining time and does not spend Credits.

A cheaper 30-second God Mode is available for 400 Credits by default. It follows the same rules and does not stack with an already active God Mode timer.

The Player Trails category contains permanent trail unlocks with one equipped at a time. The included choices use Garry's Mod's built-in LOL, love, plasma, electric, laser, and smoke materials, so they require no extra downloads. The rainbow plasma trail cycles colour continuously. Equipping No Trail disables the effect without removing purchased trails.

The Entities category contains consumable deployables. Aim at a clear floor and purchase one to spawn it there. Default prices are 10 Credits for a Bouncy Ball, 20 for a cyan Glowstick, 25 for a Health Kit, 35 for a Suit Battery, 60 for an Explosive Barrel, 125 for a five-second 250-damage TNT charge, 150 for the red damage-triggered Nuke Pack TNT, and 225 for a Friendly Healing Scanner. The red charges can chain-react. These are not permanent unlocks; every spawned item is a separate purchase.

The Helping NPCs category contains consumable Resistance reinforcements. Default prices are 175 Credits for a Rebel, 275 for a Rebel Paramedic, 325 for Barney, 350 for Alyx, 400 for Father Grigori, and 500 for a friendly floor turret. Their kills never award Score or Credits. Per-player active-spawn limits remove the oldest purchases when exceeded, and remaining purchases are removed when their buyer disconnects.

The server checks all kills, balances, live prices, ownership, equipment, and music playback. A purchase request contains only the item type and ID: clients cannot award points, submit a purchase price, or debit their own Credits.

Administrators get an Admin Prices tab in the F3 shop. Select an item, enter a non-negative Credit price, and save it. The server permission-checks and persists the change in SQLite, then broadcasts the new catalogue to all connected clients. For testing, an administrator who cannot afford an item is allowed to unlock it without a Credit charge; the server reports the shortfall and Credits remain at their current non-negative value. Set Progression.AdminShopTestingBypass to false to disable this behavior.

Every player gets one Players tab containing all SQLite player records, including offline players, sorted by all-time Lifetime Score. The public payload contains only SteamID64, name, online status, rank inputs, Score, Credits, and playtime. It never sends equipped models, weapons, trails, behaviours, or purchases. SteamID64 is used only for the explicit profile action; the list has no automatic player-detail tooltip. Offline history is loaded once when F3 opens; online rows and ranking then update automatically from the same networked Score, Credits, and playtime fields used by the regular TAB scoreboard. There is no manual refresh button, and the regular TAB scoreboard is unchanged. For admins, the same table adds model, weapon, trail, and purchase-count columns plus hover and selected-row details for enabled behaviours and permanent purchases. The server appends these private fields only to responses for an authenticated admin; it does not send them to guests and hide them in the UI. Connected players' newer in-memory totals are merged without forcing a synchronous SQLite save.

The equivalent server/admin console command is:

coop_setprice <model|weapon|music|behaviour|trail|entity|helper> <item_id> <credits>

For example: coop_setprice music song_id 500. The maximum accepted price is 100,000,000 Credits. Existing owners retain their unlocks when a price changes.

Configuration is in gamemodes/feedc0de_coop/gamemode/progression_shared.lua:

  • Progression.Ranks: rank names and Lifetime Score thresholds
  • Progression.Models: player-model catalogue and prices
  • Progression.Weapons: bonus-weapon catalogue and prices
  • Progression.Music: music catalogue, default prices, paths, and durations
  • Progression.Behaviours: toggleable ability catalogue and default prices
  • Progression.Trails: player-trail materials, colours, properties, and prices
  • Progression.Entities: consumable entity catalogue, spawn settings, and prices
  • Progression.Helpers: friendly NPC catalogue, equipment, variants, and prices
  • Progression.ShopSpawnDistance and Progression.Purchased*Limit: safe spawning distance and per-player cleanup caps
  • Progression.Hoverpack*: hover delay, rise speed, AUX drain/recharge rates, and thruster sound settings
  • Progression.Playtime*: in-memory update rate, reward interval, and Credits
  • Progression.MonsterClasses: NPC classes and their Score/Credit rewards

Catalogue prices are initial defaults. Once seeded, live prices come from the custom_coop_shop_prices SQLite table so in-game edits survive crashes and restarts.

Music files are not bundled with this repository. Every server owner must supply the audio files referenced by their Progression.Music entries, place them under garrysmod/sound/, and reconnect clients so the server can send them. The gamemode automatically registers every configured file with resource.AddFile. Keep locally supplied audio outside the gamemode source tree and distribute or back it up separately.

Player-spawned NPCs and unknown/friendly NPC classes do not award points.

Each map also gets one yellow friendly scanner near the preferred player spawn. It is an independently reusable scripted entity listed in the Q-menu under feedc0de Coop, so admins can spawn it in Sandbox and other gamemodes too. It uses normal VPhysics, patrols around its anchor, notices injured players farther away, flies toward them, and heals them in range with a visible yellow electrical beam. It cannot award Score or Credits. When destroyed it addresses its killer with a random farewell and falls as a gravity-enabled physical wreck for 25 seconds. Its Scanner.Tail bone has a subtle client-rendered wiggle; this is deliberately isolated from the upright VPhysics flight controller. The gamemode—not the reusable entity—creates a new living scanner at the same spawn anchor after five seconds. The defaults can be adjusted with gc_friendlyscanner_enabled, gc_friendlyscanner_healradius, gc_friendlyscanner_searchradius, gc_friendlyscanner_healrate, and gc_friendlyscanner_respawntime.

The gamemode establishes its map anchor only after the first player's position has remained free of teleport-sized jumps for several samples. A downward brush trace acts as the scanner's floor-distance sensor: every patrol target, initial Q-menu spawn, and physgun release resolves to the local floor plus the hover offset and is clamped below the ceiling. This lets the scanner glide up and down stairs and return to flying height after being placed low or high.

Cooperative bots

The gamemode maintains two naturally named player bots by default. They record the route taken by living humans and follow its newest reachable breadcrumbs around corridor corners on maps without a navmesh. They operate doors and buttons in their path, jump/strafe around short obstructions, and use a delayed safe-position catch-up only after route following has failed. They shoot hostile NPCs in sight and respawn after three seconds.

Bots evaluate every weapon they carry, switch away from empty weapons, reload from reserve ammunition, and seek visible unowned map weapons, ammo, health and armour while out of combat. They ignore player-created weapons and construction tools, so they do not steal equipment placed for another player.

Steam and the scoreboard still report them as bots; their display names do not carry a redundant [BOT] prefix. They are excluded from progression, SQLite player statistics, human difficulty scaling, scanner spawn anchoring, and campaign failure decisions. Set gc_bot_count from zero through eight, then run coop_bots_refresh to reconcile the population immediately.

Purchase, equip, behaviour, and price responses update the existing F3 controls in place. They do not recreate, close, move, or scroll the window, so there is no visible frame flash and the selected tab and scroll position stay untouched.