Tools
Tools: How I built a Quake Live config editor using JavaScript and AI.
2026-02-27
0 views
admin
Introduction ## Basic Framework ## Research / Time Schedule ## More Advanced Additions to the App ## CVAR Dependencies in the JSON and Info Panels There are plenty of "config guides" online for the game Quake Live (Steam's free-to-play remake of the popular FPS Quake 3: Arena), and I actually DID develop my config from some of those online guides. The only thing is, a lot of them were made from 2012 and before, and since a lot of CVARs in the game have been deprecated and no longer used by Quake Live's engine, I was putting a lot of time into researching what commands are still actively used, and making adjustments to my autoexec.cfg. In my search to making the ultimate, competitive style config (A config that gives you high frames per second, a clean HUD, and modifications that use pro suggestions/recommendations for high performance [and not necessarily aesthetics/visuals]), I decided I wanted to try making my first app... a Quake Live config editor. A little background about myself, I graduated from a pretty popular online college with a B.A. in Web and Graphics design but during my coursework I had little to no exposure to heavy duty coding. Most of the time I spent with the Adobe Creative Cloud on visual projects. Since then I have spent hundreds and even thousands of hours studying JS, advanced CSS, frameworks like Tailwind and Bootstrap, and Git. In those hours of training I developed quite a bit of basic and intermediate JS understanding, I've worked on practical Udemy courses like JS Bootcamp by Brad Traversy and "50 HTML/CSS/JS Projects in 50 days" (a lot of fun), but not enough to create a fully functioning online App for my purposes. So I thought I'd try making the app with AI. First, I built the basic framework of the site with ChatGPT (I got a Pro subscription free-trial for 30 days and went wild.) This gave me my basic structure, a index.html embedding a link to Tailwind's free CDN, a /js/app.js including the backbone JS, and an /js/data/cvars.json which I structured the entire website's content in. (Roughly 300 CVARs and every single Bind from the Quake Live in-game settings interface + more [custom aliases/scripts, useful legacy binds). With a combination of subscriptions from Google Gemini, ChatGPT, and Grok.ai, I started plowing away. I had to find out a few things for my app: 1) What were each setting's "default" setting. To do this I created "tier"s in the JSON. I set a "tier": "default" to every value that each CVAR in question's defaults were, and loading the page for a user would initially parse the defaults in the input boxes for each selection. 2) What were the "recommended" settings? What do the pros suggest using? What settings SHOULD be changed from default for better gameplay, easier fragging, more control, better framerates, quality of life? Some of you old-school Quake 3 players know the default r_picmip values are NOT competitive. So how do I make the user know that changing picmip to 5 would be recommended? In the JSON I created "tier's" for "recommended" (And also, a tier for "recommended_default", when a setting was recommended but also the default value.) 3) What should I explain about each CVAR? To be honest, I could have made a half-attempted app, but I spent dozens of hours making sure I fully described each setting and it's uses, and especially included suggestions for competitive standards. For example, for the "sensitivity" CVAR, I didn't just write "Controls how fast or slow your mouse moves the crosshair ingame.", but rather, I went elaborately, in a way that people could understand the mechanics of the setting, helping people align their game more like professional Quake players... Sensitivity: "The master multiplier for your mouse speed. Effective Sensitivity (eDPI) = Mouse DPI × Sensitivity. Lower values (e.g., 20-40cm/360) generally offer better tracking consistency (LG), while higher values favor fast reflex flicks (Rail). In 2026 QPL, most pros use 1.5-3.0 with 400-800 DPI for consistent aim." 4) I had to create certain "ui"s for each CVAR. If a setting only takes in a 1/0 value, I created checkboxes. If a setting allows for a string, I provided pre-recommended values (like enemy models Keel/bright), and then programmed the app in the JS to provide a custom input field below the drop-down with prerecommendations, allowing for text to be inserted. I created a CFG Preview div, so when the user clicks on a category (Categories from the JSON entries divide the structure of the navigation on the page. Main categories get a certain #HEX color and subcategories rest below it in plain white text), the text in the CFG Preview panel automatically scrolls to the exact location of the CVARs in question, allowing the user to see in real-time their edits. I color coded my app. Default values are colored yellow, Recommended values are colored green. That way, the app is interactive and users can distinguish between what the game provides you with at stock settings and what changes are recommended to implement. There were certain implementations that took a long time to figure out, like how to make a binding system where I could allow players to set their binds to keys like they were exactly in the game settings menu, even with the features of noticing when a key has already been bound, you get a big error saying "Duplicate..." And adding custom scripts, I had to create popup module that opened a text-based field with my pre-populated scripts I provided in my app, and the feature of having the user add their own scripts to the config. I included color boxes that allow players to set their railgun beams and outer spirals visually, just by clicking. I included a HEX grabber, so the user could change their forced enemy model skins to certain HEX-Alpha values, giving a "right in your face" color module that lets you see what you're going to get. I have sliders for certain settings like "sensitivity" and "cl_mouseAccel", allowing the user to change the values with ease. I included distinction between "enums" and "float"s, (enums being settings that take values with single digits, 1-2-3 etc.., and floats being settings that take in decimal values, such as 1.33). I told AI to take away the focus effect on my input boxes, remove the up/down arrows that are pre-designed into the fields, and create custom up/down arrows aligned perfectly to the right of my input boxes, which act upon those numerical values based on the "step"s defined in the JSON. Essentially, I gave the user A) The easiest way possible to adjust each setting.
B) A visually pleasing way, too.
C) An effective UI/UX experience to work with. In school, I learned that in design things should be "Simple as can be", "Pleasing to the user", "Apparent and obvious", and "Compendious". I used my knowledge of effectual design, my web design expertise, and the best ability to turn my conscious ideas into writing (AI prompts) to generate the JS. I even added "warning" messages that appear when a master toggle is set off. For example, in Quake Live, there's more graphic settings than Quake 3 provided back in the day... one of them is called Post Processing, which allows for more advanced graphical enhancements like bloom and vignette. When a user sets "r_enableBloom" to 0, it's dependent values hide (DIV's are set to display: none), and an information message with a font-awesome icon and blue colorized text appear: "ℹ️ Enable Bloom to unlock the advanced Threshold, Intensity, Saturation, and Filter Pass sliders below." Note: these dependencies weren't too difficult to implement, just javascript recognizing the JSON file entries with "dependsOn": [{ "cvar": "cg_drawCrosshairNames", "op": ">", "value": 0 }], All of these changes were implemented one by one, asking Gemini to "add a feature" to my app, with direct instructions. A lot of times, things wouldn't work, and I'd have to try different prompts. My knowledge of HTML/JS/CSS helped quite a bit, but the amount of time saved by using AI changed the time frame that I created the app from start to finish tenfold, possibly more. My passion for gaming drove me. I used to play Rocket Arena 3 on Q3 back in middle and high school. I used to watch pro players (czm, Fatal1ty, Zero4, Cooller, Fox, Toxicity, and more) all the time, in .dm_68 demos. If it wasn't for my passion for configuring Quake, and the amount of knowledge I already had in the modifying of the game (from tons and tons of changing my configs in my early years), I wouldn't be driven to put the time in to my app. But what I have to say is, if you have enough of a reason to do something that you want to do, you will find enough of a way. Passion + Interest + Knowledge + Effort = Results. In this case. + AI too, :) At least that's what I just made up from the top of my head. One of things that frustrated me the most, however, was that I can't say that I know how all the JS works. That's because I didn't build it entirely myself. During this project, my goal was to create an app that others would use and love. I didn't make the requirement for myself that I had to have programmed it with my own head-knowledge, line by line. I didn't. If I had told myself that, I wouldn't be proud of my result right now, because in fact I didn't do that. What I did tell myself during the development of this project, is I'd go back to training, and the next time I make something, I will make it by my own hand. Back to JavaScript lessons I go! By the way, if you made it this far, here's the live project. https://quakeliveconfigeditor.com Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
"warnings": [ { "type": "info", "message": "Enabling m_cpi completely changes the engine's sensitivity math. Your current Sensitivity value above will feel drastically different and need readjustment.", "when": { "cvar": "m_cpi", "op": ">", "value": 0 } }
], Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
"warnings": [ { "type": "info", "message": "Enabling m_cpi completely changes the engine's sensitivity math. Your current Sensitivity value above will feel drastically different and need readjustment.", "when": { "cvar": "m_cpi", "op": ">", "value": 0 } }
], CODE_BLOCK:
"warnings": [ { "type": "info", "message": "Enabling m_cpi completely changes the engine's sensitivity math. Your current Sensitivity value above will feel drastically different and need readjustment.", "when": { "cvar": "m_cpi", "op": ">", "value": 0 } }
], - 50% of the time I was researching CVARs from Quake Live's current list of active commands, including sensitivity and acceleration cvars, team and enemy model/skin cvars, crosshair and crosshair dynamics, graphics and lighting, sound settings, network and connection settings, and many many more...
- 50% of the time I was modifying the JS (the site is so simple in structure! Only four files: (1 .html, 1 .css, 1 .js, and 1 .json)
how-totutorialguidedev.toaimlgptchatgptnetworkjavascriptgit