February 23: CSQC ModelViewer ... (Download: Zircon Beta #87)
Made a CSQC Model Viewer to quickly view the models in any mod that does not require the use CSQC to function properly (99% of Quake). This will let you look through a mod's models rather quickly. This tool is a single .pk3 file that will require upcoming Zircon Beta Release 88.
Pictured: Looking through Travail's models -- one of the bosses and then the Uberscrag.
Hammering this out real quick help find some small adjustments needed for some of the work in progress features. This CSQC tool extensively uses new Zircon User-Interface API.
February 21: Vis Ignore Fix (Download: Zircon Beta #87)
In DarkPlaces CSQC -- as I understand it -- setting entity.render = RF_WORLDOBJECT or RF_DEPTHHACK should cause an entity to render even if it fails visibility testing, but it is not doing that.
Pictured: Quick tool to assist positioning of attachments to player.
The fix.
if (ent->crflags & (RENDER_NODEPTHTEST|RENDER_WORLDOBJECT)) {
r_refdef.viewcache.entityvisible[i]= true;
continue;
}
It almost certainly had to have worked in the past, although this feature is a bit obscure -- and after some checking it seems neither Xonotic and Blood Omnicide (2 of the most complicated DarkPlaces works) -- neither seem to use RF_WORLDOBJECT but both use RF_DEPTHHACK.
I'm going to hard commit to taking the "W" and not investigating this further. 😎
Update: RF_WORLDOBJECT works really nice compared to RF_DEPTHHACK for what I am doing. RF_DEPTHHACK basically draws on top of everything (wrong for this), RF_WORLDOBJECT just ignores vis (perfect!). Although it was slightly brokesters, it is so nice that RF_WORLDOBJECT was written as a feature.
February 21: Vis Ignore Fail (Download: Zircon Beta #87)
DarkPlaces seems to not be honoring RF_DEPTHHACK, RF_WORLDOBJECT and other "always draw without checking map visibility" attributes in CSQC. Not sure if this is a bug introduced with the "DarkPlaces Beta Vis Fix" that reworked the map visibility process, but what is clear that r_novis 1 will still draw everything.
Attempt to trace through to see exact where this behavior is ignored in the engine, so far not able to identify it.
Note to self: Check exterior models (RF_VIEWMODEL etc.). This potential bug is a minor inconvenience, but if exterior view models are affected -- these are extra "added in weapon models" -- that would be a "big deal".
One advantage of retaining full DarkPlaces compatibility with a mod is to easily check against different versions of DarkPlaces or older versions of Zircon to notice differences. However, with Inventory and User-Interface API the QuakeC I am using for this is not going to work at all -- so I would have to draft up test cases that are backwards compatible to do this testing. I don't think that is in the cards right now.
I think this is only a "nuisance level" issue -- there are few mods using RF_DEPTHHACK and RF_WORLDOBJECT ... Xonotic perhaps and maybe BloodOmnicide ... but I was planning on using them here because I need visibility ignore drawing in CSQC for inventory but I already have a workaround that should suffice for now.
February 19: Largest Hornet's Nest Cleared (Download: Zircon Beta #87)
Everything the player is equipped with is in a text CSV file with column headers specifying item names, their attachment offsets/angles/scale etc. QuakeC accesses the inventory data by item name/column header name and tells the user-interface how to display it.
This was the murkiest task on the todo list and one that was going to be a roughest road to chart out.
Now it is a completed item 😎
February 18: Inventory API Continued (Download: Zircon Beta #87)
Inventory API is hammered out in theory, coded and passed initial tests with some QuakeC tests.
Accessing it looks like the following -- everything is a string, but the API allows accessing it in a way that automatically converts -- early on working on Interface API it was "all strings" and the QuakeC was messy with ftos(mystring) everywhere --- (ftos is "float to string" function) -- and weeks ago I reworked Interface API to have separate output functions so that QuakeC using it was cleaner. Same here.
float numcolumns = inventoryreload(1, "inventory.csv"); // 1 is Inventory handle #1
string s = getinvs(1, "longsword", "Model"); // Get string
vector v = getinvv(1, "longsword", "Offset"); // Get vector
float f = getinvf(1, "longsword", "Scale"); // Get floating point
It supports multiple inventory lists. The first column is considered the "key" -- and should be unique -- and the first row is considered column headers. There are not any predefined fields, that is for QuakeC to figure out.
The reason for supporting multiple inventories ==> there could be multiple categories of items that are radically different and do not really integrate well together into a single "table".
DarkPlaces in many places is rather loose on limitations -- and this is practiced throughout the codebase and as I have worked with the codebase I have tried to apply that style of thinking -- so there can be 8 separate inventory lists.
Will see how it holds up after put through real road testing.
February 18: Text Parsing (Download: Zircon Beta #87)
Don't really enjoy working on text parsing, but with engine coding there is going to be text parsing and at times quite a lot it. And so here we are today.
The best way is to do a great job with it so it does not need revisited very often.
February 16: The Train Keeps Moving .. (Download: Zircon Beta #87)
February 15: More ... (Download: Zircon Beta #87)
Moddb article editing is a little "different" at the moment (site upgrade?) .. anyways wiring continues ...
Much more to go ... somewhat astonished by the rather monsterous amount of work required to exactly hammer these out ... although this part is not "hard" to me -- much trial and error and tall stacks of grunt work. And a lot more of that to come too.
February 14: Wizards ... (Download: Zircon Beta #87)
Making the Quake Guy look like a wizard thus far has not been easy.
February 13: The Grind ... (Download: Zircon Beta #87)
Coding is a grind. If you want X, it may require a thousand things to get X. You do them one at a time.
February 13: Slight Misdirection ... (Download: Zircon Beta #87)
Started towards wiring up some user interface code -- debating whether or not the interface seen below should "pause the game" or should run while monsters are moving -- in theory ... in practice this is going to support multiplayer either at the start or later on and the idea it will pause is a non-starter.
However, in single player, I want it to pause the game. Now we have a new problem! Here's why ...
Pictured: DarkPlaces did such a great job takng things so far and adding so many features for rendering more than one scene. I don't offhand know of anything that uses it -- I'm not sure Xonotic even does, maybe Blood Omnicide does somewhere -- but that existing support was extremely helpful to extend it further. The rendering of an extra scene is what renders our Quake guy -- and the user-interface seen draws on top of the "player only" scene render.
In CSQC, you have "time" variable and frametime variable. These stop when the game is paused and it renders our Quake guy. Without time variables, no animation is possible. Fortunately, probably due mostly to Menu QuakeC, there is a gettime() function that returns "realtime" -- but now QuakeC nextthink becomes useless because it uses "time" (like it should). For animations, we need frametime so yet another thing that must be written. Then discovered the CSQC function prototype didn't fully reflect the actual engine code, which is quite normal really considering the several hundred functions.
And all that has been written now.
But is an example of unforeseen obstacles that consume a bit of time and energy. These are to be expected.
Victory is being able to code and eliminate these things off the todo list. The opposite of this, I can imagine a great many projects get stopped by obstacles like this. Thankfully, those kind of things tend to be "nuisance level" here.
February 12: More 79% Work ... (Download: Zircon Beta #87)
DarkPlaces has about 79% of road paved for what I am currently looking to do. I have to code the remaining 21%. On the other hand, the backbone of this is Zircon User-Interface API that interacts with client-side QuakeC.
Not Pictured: The Quake Guy is animated subtley in "Character View" or whatever this gets called.
Pictured above ... the world is being drawn twice. Except the 2nd world draw pass only draws the Quake dude. For efficiency, 3D draws first and then 2D is drawn over top of that. To get the Quake dude on the interface .. there is a "cut-out" specified and we literally draw around it. When DarkPlaces clears to draw a 3D scene, it clears to black --> in the next Zircon you can specify the color which is brownish when we draw the "Quake dude only 3D pass". The cut-out communicates to CSQC where the 2nd pass is to be drawn. And everything resolution scales -- or at least it should.
Still don't have everything I want here, more to go. I'd say this part is 20% done.
February 11: Brutality ... (Download: Zircon Beta #87)
In the last week, thought about how to get DarkPlaces to do some things that it doesn't quite want to do -- but thankfully was maybe 79% close to being able to do them. The final 21% required coding and some planning.
Pictured: On the right track towards what I want to do. This is the current "stopping point", but I haven't dealt with on-screen inventory in the above, other than our "Quake dude" has gear on.
I had a gameplan in mind for the coding, but without any mental picture of something precise to strive towards coding, I was aimless and lost in desert a bit -- but that is done now.
I had to code 2 rather preposterous things -- the final one was the height of absurdity. The above "form" has a cutout -- an area of the screen where it does not exist. And it draws around that area which requires calculating image s and t coordinates.
Why would I code such a thing? The answer is I wanted it. I couldn't get 100% of what I wanted economically, but I could get 90% but the road was twisted and filled with briar patches. And I went full speed into that briar patch without hesitation.
February 10: Out of the Muck (Download: Zircon Beta #87)
I ended up drafting up some concept pics that will work, so I have a direction for what I am looking for with an inventory interface -- so should be unstuck and with any luck quite a code barrage is will be taking place soon.
Pictured: "devel" version 3 -- totally unrelated to current events, but happened to be a map in the maps folder for testing. ("devel" is an open source test map for Xonotic with several special shaders and a version 3 of this map was released by the author, Julius, around Christmas.).
February 8: ... (Download: Zircon Beta #87)
Had to do some touchups that aren't quite obvious with the below pic, but had to work on textures/models a little because not able to get something that looks cohesive enough be inspired to get the user interface right. And also was a bit stuck there too -- not with the code but with getting a mock-up that looked like a fit. Maybe getting "unstuck" soon.
February 6: Getting The "Feel" (Download: Zircon Beta #87)
Working on the inventory screen, the idea is to be able to have inventory and equip your dude drag dropping and such.
Needed to mock up something to get some "feel" / motivation for ironing out the interface. I have some interface prototyping done but inspiration and getting a feel for what the interface should look like matters.
February 6: VF_ View Properties (Download: Zircon Beta #87)
Extended the CSQC renderscene view properties to allow setting clearcolor and extras masks to avoid drawing certain entity types in a scene.
February 5: Immerse ... (Download: Zircon Beta #87)
I have tried to plot a direct route through Inventory API. After a couple of false starts, simply going to attack.
Will see how far progress goes on "time to go all in" night #1 ...
February 2: Inventory API ... (Download: Zircon Beta #87)
Path is murky -- each separate battle one at a time -- foundations first, then refine with wave after wave.
Load the inventory, communicate the inventory to the client, display the inventory come first ... make sure the data gets into save games ...
All of this combined with the other unmentioned 5 pieces is a "nightmare level" task -- actually laughing a bit because = true --- but once a decent sized dent is made into this task, I expect it to be fun.
(One thing that will make the end result enjoyable, the Inventory API and the User-Interface API will be able to work together as an option, keeping actual client-side QuakeC streamlined by not needing to have a lot of code).
January 31: Animation Smoothing CSQC ... (Download: Zircon Beta #87)
This explains how the animation smoothing in CSQC works because unlike vanilla Quake where any given Quake engine has the animation smoothing in the engine code, we have to do it ourselves. And we want to light this model ourselves. Posting most of the code because of the scarcity of this information / documentation.
Smoothing:
void QGUY_NextFrame ()
{
self.frame ++;
if (self.frame > self.frame_high) // 22
self.frame = self.frame_low; // 18
self.frame2 = self.frame + 1; // Future frame.
if (self.frame2 > self.frame_high) // 22
self.frame2 = self.frame_low; // 18
self.frame_starttime = time;
self.think = QGUY_NextFrame;
self.nextthink = time + self.frame_interval;
}
Lerp Calc:
void QGuy_Draw3D ()
{
if (!autocvar_qguy)
return;
// Baker: What percent of time has progressed towards "nextthink" (future frame time)
// We must subtract out qguy.frame_starttime and divide by the interval.
float lerpfrac1 = (time - qguy.frame_starttime)/qguy.frame_interval;
qguy.lerpfrac = lerpfrac1;
// Baker: Guess what? If there is bloom here, we have double bloom.
// We don't want double bloom ...
float oldbloom = Maybe_Push_NonZero("r_bloom");
Lighting:
// Where is our camera ...
var vector autocvar_qguy_vorg = '351 567 123';
var vector autocvar_qguy_vang = '22 113 0';
// Where is our dude ...
var vector autocvar_qguy_org = '324 618 84';
var vector autocvar_qguy_ang = '0 250 0';
// Lighting for our dude ...
var vector autocvar_qguy_ambient= '0.5 0.5 0.5';
var vector autocvar_qguy_diffuse= '0.85 0.85 0.85';
var vector autocvar_qguy_dir = '180 0 0';
void QGUY_Init ()
{
qguy = spawn ();
qguy.classname = "qguy";
qguy.origin = autocvar_qguy_org;
qguy.angles = autocvar_qguy_ang;
qguy.model = "progs/player.mdl";
qguy.drawmask = MASK_SIDEVIEW_256;
qguy.renderflags = RF_MODELLIGHT_4096; // <=== WANT TO LIGHT OURSELVES
qguy.effects = EF_NODEPTHTEST_8192;
qguy.modellight_ambient = autocvar_qguy_ambient;
qguy.modellight_diffuse = autocvar_qguy_diffuse;
qguy.modellight_dir = autocvar_qguy_dir;
precache_model (qguy.model);
setmodel (qguy, qguy.model);
setorigin (qguy, qguy.origin);
qguy.frame_low = 18;
qguy.frame = qguy.frame_high = 22;
qguy.frame_interval = 0.20;
Run_As_Self (qguy, QGUY_NextFrame);
}
January 31: Start With Nothing ... (Download: Zircon Beta #87)
Ok ... the idea here is that when we are done, we will be able to pimp out the Quake dude with gear with a full blown inventory user-interface.
But it starts with this ... and the Quake guy is not even animation smoothed because he renders in CSQC and haven't draw that part. And he is fullbright. DarkPlaces allows setting precise lighting on a model in CSQC which is nice.
Pictured: The same CSQC as CSQC Rearview Mirror is what allows us to draw a scene with no world and only draw a specific model in the scene.
I won't be doing much work converting models -- I want to get the code support done .. so at the end of the day Karl might be more pimped out than our Quake guy.
Pictured: This is Karl. You can tell that it is Karl because he has a name badge.
January 31: Inventory ... (Download: Zircon Beta #87)
Going to try to eliminate inventory as a "problem" and this is 4 different huge issues combined.
And for 1/4 of this, I do not have a plan -- and I generally try to avoid tasks where I don't have a linear plan to complete it -- but I want these guys off the todo list.
This could take a week. First screenshots and concept work -- however, maybe even later today ...
Ground rules: Inventory must save in save games naturally, carry across levels, work in multiplayer and be exclusively controlled by the server.
January 30: Phase 1 Close .. (Download: Zircon Beta #87)
Have most of everything I wanted to do for Zircon User-Interface QuakeC API Phase 1 done ... and it does more than initially planned.
January 29: Context Menus (Download: Zircon Beta #87)
Right-clicking on things brings up context menus that allow a more fine-tuned action on something.
Case in point, in the File Open Dialog ... I want to be able to delete junk files I don't want any more.
Finished 95% of it, but walking through how I want it to interact with QuakeC took some meditation. The final 5% is positioning and sizing and then getting a nice example to show = no pics just yet.
Pictured: Phase 1 won't have a silver bullet to dramatically simplify inventory system user-interfaces. That is in a very likely Phase 2. It is possible Phase 2 happens and completes in February, but considerations for Phase 2 need to happen after Phase 1 is done.
Pictured above: A very comprehensive CSQC inventory system -- the supporting code is an absolute behemoth. The pictured inventory system encodes and decodes inventory from a string, transports across levels and save games and works in multiplayer and is exclusively controlled by the server -- supports drag dropping of items, some items like coins will stack, and extra storage (remove the backpack, storage slots = less). I do not like large and complex code, but even now haven't quite had the "Eureka" moment to figure out how to get it to collapse into simplicity, but I want to do such.
January 28: Encoding "Fun" (Download: Zircon Beta #87)
Have a system in place that stores lists, but values are quoted and there is a list separator delimiter that is usually a comma. Then you have the issue, how to put quotes and commas into a list and have it encode if those have special meaning.
So I detect that case and encode the list using base64 resulting in no commas or quotes ... MSxzdHVmZiAsMiwCICwzLHN0dWZmIA==
Not sure if there isn't a "better" way to do it, but it works. Now on to actually important stuff I want to be working on, because NO ===> I do not want to working on the inner mysteries of text parsing.
Take a stake, jam it into Dracula and move on ...
January 27: The Twilight Zone (Download: Zircon Beta #87)
Continuing refinement of User Interface API -- excellent is simply not good enough and re-wrote a redesign of some of the interface aiming for as close to perfect as possible.
The reason "excellent" is not good enough ==> will permanently have this interface as "how to do things easy" and will have code using it.
"Form Systems" take the complex and make it easy -- hiding the complexity behind a veil of simplicity.
Reworked the API to reduce the number of lines of QuakeC by about half in some cases -- and from several lines to a single line in some other cases.
It's Dungeons Or Bust Time (Download: Zircon Beta #87)
The goal is that by the end of February to have a full-fledged "Dungeon Experience" mod completed.
Supporting this is the Zircon User-Interface API for Client Side QuakeC ... which is still in progress but closing in to the goal.
Zircon User-Interface API makes -- otherwise impossible -- largely text based user-interfaces available to QuakeC that can be heavily customized and in the future should allow some fun otherwise impossible mods to exist.
Meanwhile .. don't forget to enjoy Q.U.A.L.K.E.R. 0.4: