ddf editing; looking for features

Are you experiencing a problem? Maybe you can't get your scripts to do what you need, or are frustrated by a feature you just can't seem to get working? Let us know about it here and we will try our best to help you out!
User avatar
Marscaleb
Posts: 89
Joined: Sat Jun 25, 2016 12:57 pm
Location: California or Utah
Contact:

ddf editing; looking for features

Post by Marscaleb »

I've been going through and re-writing the default dynamic lights settings for Doom.
Once I learned some of the basics of ddf, it has been pretty straight-forward. But there are some certain effects I am having trouble pulling off correctly.

Specifically, I am having trouble with getting the lights to flicker to simulate a flame.
Some of these have come out pretty good, like the basic candle, which I made with this:

Code: Select all

[BLACK_CANDLE:34]
RADIUS=16;
HEIGHT=16;
DLIGHT.TYPE=QUADRATIC;
DLIGHT.INTENSITY=100;
DLIGHT.COLOUR=#ffe74b;
SPECIAL=NOSHADOW;

STATES(IDLE)=CAND:A:5:BRIGHT:dlight_set(110),
cand:a:2:bright:dlight_set(80),
cand:a:8:bright:dlight_set(100),
cand:a:1:bright:dlight_set(85),
cand:a:3:bright:dlight_set(125),
cand:a:1:bright:dlight_set(79);
This generates a nice flickering pattern, suitable for a single small candle, which is a little hard to tell that it is repeating exactly.

But there are two problems I am coming across.

The first is that most things that have a flame have an animation, and adjusting the dynamic light while keeping the animation playing at a proper rate is tricky. Either A) I adjust the light in synch with the animation, which is acceptable but doesn't look as nice, or B) I have a very long sequence of instructions to loop through several changes from the light and cycling the animation properly, which isn't exactly a major problem but we should be able to set up a better system.

The second problem is that because these scripts execute in an exact order, they are all synchronized in an exact pattern. When you have multiple lights of the same type near each other, which happens fairly frequently, they all flicker in unison and it doesn't look natural at all. Areas with a lot of identical things (like the start of Map22 in Doom 2) look horribly atrocious.

As I was thinking about these problems, the first thing that came to my mind is that I could really use some sort of randomizing feature. Is there any such feature already built-in to the ddf scripts? I did not see any on the wiki page. It would be a useful option to have because it could be used in a myriad of ways, not just with these lights. Make random drops from enemies, for example.
So my first question here is, is there any options to create random variables in ddf, or otherwise to randomize elements, especially for individual instances?

As I thought more about exactly how I want to approach this issue, however, it occurs to me that the better (and in some ways simpler) solution to these lights would be to create a command to make dynamic lights flicker. I see there is already an option to make a light fade. I am thinking something that gets put into the script in the same manner, a command that says "DLIGHT_FLICKER(x,y)" where x is the lowest brightness and y is the maximum brightness, and then the dynamic light instance will follow a pattern of semi-randomly jumping its brightness value around.
This would solve both of the issues and then some. Each light can flicker independently, the script itself would be very short, and on top of that, the actual flickering pattern could written to better simulate a natural pattern than one might have done with ddf script originally.

That's my idea anyway, but I don't exactly know how feasible this is.

Sandstormer
Posts: 127
Joined: Sat Nov 22, 2014 3:12 pm

Re: ddf editing; looking for features

Post by Sandstormer »

I've been playing around with the lighting as well - mainly to try and create a flickering effect for the torches and a corona effect for the small bollard lamp. I've managed a similar effect to what you're trying to do by defining additional idle states (IDLE.2; IDLE.3; etc.) that contain a different flickering sequence and then adding an A_JUMP for each state so that the light randomly jumps back and forth between the different flickering sequences. It's still a work in progress, but it is something to try and see if it works for you.

User avatar
RUNSABER
Posts: 132
Joined: Sat Mar 14, 2015 3:10 pm

Re: ddf editing; looking for features

Post by RUNSABER »

Glad you're loving DDF bro, its really tight. :)

There are two out of many ways I've discovered to created cool flickering lights. I used an effect to create a pulsing radioactive barrel for Doom II similar to ones I describe.

Try working with the NORMAL and BRIGHT functions of the thing's state. When using NORMAL, there are NO dynamic lighting uses, nor does the sprite render in full bright in sector-based lighting. When you set the state to BRIGHT, you have static dynamic lighting. Use LIT to control the universal brightness of the dynamic light. As so:

Code: Select all

NULL:A:1:NORMAL:NOTHING,
NULL:A:1:BRIGHT:NOTHING;
//creates a fast-strobe effect due to low tics

NULL:A:1:BRIGHT:NOTHING,
NULL:A:1:LIT80:NOTHING,
NULL:A:1:LIT60:NOTHING,
NULL:A:1:LIT40:NOTHING,
NULL:A:1:LIT20:NOTHING,
NULL:A:1:LIT1:NOTHING,
NULL:A:1:LIT20:NOTHING,
NULL:A:1:LIT40:NOTHING,
NULL:A:1:LIT60:NOTHING,
NULL:A:1:LIT80:NOTHING,
NULL:A:1:LIT100:NOTHING,
#SOMESTATE:1;
//creates a fast pulsing light - adjust tics for longer phases
Make sure to point your states back to the starting frame to loop a seamless effect. DLIGHT_FADE only works with the translucency of the light whole DLIGHT_SET works with the radius/intensity. Using the Normal and Bright functions of the state makes everything seamless and gives you more freedom to use ambient sounds, attacks, spawners or other actions alongside controlling lights.

I created a tutorial on dynamic lighting, the different types and how to create and use them but my computer has a habit of deleting things. Which is why its taking me longer to release mods. I have to be
careful as to not lose work and save/test along the way.
Official 3DGE64 Project Portal - Public Repository for 3DGE 64.

User avatar
RUNSABER
Posts: 132
Joined: Sat Mar 14, 2015 3:10 pm

Re: ddf editing; looking for features

Post by RUNSABER »

I've also been spamming jump actions in my DDF lately, we can teach you about them and how it works. I may be able to write an article for the wiki as a better reference.
Official 3DGE64 Project Portal - Public Repository for 3DGE 64.

User avatar
Marscaleb
Posts: 89
Joined: Sat Jun 25, 2016 12:57 pm
Location: California or Utah
Contact:

Re: ddf editing; looking for features

Post by Marscaleb »

I think we need an update to 3DGE with some new dynamic light features.

Not just adding a light flicker, but maybe a number of new patterns that people might want to use.
I've written up a few ideas in some pseudo-code. I'm new here and haven't looked at the source code, let alone the functions between the ddf and the dynamic lights, so I don't know how compatible it would be. I'm really just writing this to express the ideas.

A small fire flicker; the kind you would see from a single candle.

Code: Select all

//overall a very steady flicker, usually at or near full brightness, occasionally dipping into its darker values for a tick or two.

DLight_SFireFlicker (int MaxBrightness, int MinBrightness, color Brightcolor, color DarkColor) {

/*
MaxBrightness: The highest value for the light's intensity
MinBrightness: The lowest value for the light's intensity

BrightColor: OPTIONAL.  The color of the light when it reaches its brightest value.  Default is the light's given value.
DarkColor: OPTIONAL. The color of the light when it reaches its darkest value.  Default is the light's given value.

For best effect, use a higher saturation color for the dark color, and a lower saturation color for the bright color.

*/


int tickCounter=0;
int phaseCounter=0;
float currVal=0;

tick {

	tickCounter--;

	if (tickCounter <= 0) {

		tickCounter = randomRange(1, 3);
		phaseCounter--;

		if (phaseCounter <= 0) {
			phaseCounter = 4;
		}
		if (phaseCounter == 1) {
			currVal = randomRange(0, 0.35f);
			if (tickCounter == 3) {
				tickCounter = 1;
			}
		}
		else {
			currVal = randomRange(0.75f, 1f);
		}

		DLight_SET( Math.Lerp(MinBrightness, MaxBrightness, currVal);
		DLight_Color( LerpColor(DarkColor, BrightColor, currVal);

	}

}

}

LerpColor (color ColorA, colorB, float t) {

// I have no idea how the color values are stored in this engine, so I am completely making this crap up.

return new color(
	Math.Lerp(ColorA.red, colorB.red, t),
	Math.Lerp(ColorA.green, colorB.green, t),
	Math.Lerp(ColorA.blue, colorB.blue, t),

}
A large fire flicker; the kind you would see from a torch or campfire.

Code: Select all

//a more chaotic flicker, jumping between high and low values constantly, but typically rather bright.

DLight_LFireFlicker (int MaxBrightness, int MinBrightness, color Brightcolor, color DarkColor) {

/*
MaxBrightness: The highest value for the light's intensity
MinBrightness: The lowest value for the light's intensity

BrightColor: OPTIONAL.  The color of the light when it reaches its brightest value.  Default is the light's given value.
DarkColor: OPTIONAL. The color of the light when it reaches its darkest value.  Default is the light's given value.

*/

int tickCounter=0;
float currVal=0;

tick {

	tickCounter--;

	if (tickCounter <= 0) {

		tickCounter = randomRange(1, 2);

		if (randomRange(1,3) == 1) {
			currVal = randomRange(0, 0.45f);
		}
		else {
			currVal = randomRange(0.55f, 1f);
		}

		DLight_SET( Math.Lerp(MinBrightness, MaxBrightness, currVal);
		DLight_COLOUR( LerpColor(DarkColor, BrightColor, currVal);

	}

}

}
A random flicker like you would have from an electronic light that is wearing down.

Code: Select all

DLight_ElecFlicker (int MaxBrightness, int MinBrightness = 0, byte FlickerRate = 64, color Brightcolor, color DarkColor) {

/*
MaxBrightness: The value of the light's intensity when it is fully bright or "on."
MinBrightness: OPTIONAL. The value of the light's intensity when it is flickering, or "off." Default is 0, which makes the light flicker between being completely on or off.

FlickerRate: OPTIONAL. Sets how frequently the light flickers.  Values closer to 0 will rarely flicker and mostly be a steady light.  Values closer to 255 will mostly be off and occasionally will flicker on.

BrightColor: OPTIONAL.  The color of the light when it reaches its brightest value.  Default is the light's given value.
DarkColor: OPTIONAL. The color of the light when it reaches its darkest value.  Default is the light's given value.

*/

bool bOn = true;
bool bOnLastFrame = false;

tick {
	bOn = (randomRange(0, 350) + FlickerRate > 200); //I don't know if this would actually work; I've never tried to add dynamic weight to a random variable before.
	if (bOn != bOnLastFrame) {
		if (bOn) {
			DLight_SET(MaxBrightness);
			DLight_COLOUR(BrightColor);
		}
		else {
			DLight_SET(MinBrightness);
			DLight_COLOUR(DarkColor);
		}
	}
	bOnLastFrame = bOn;

}

}
A simple modulation, cycles linearly between bright and dark across a given amount of time. (This would be easy to make with a ddf file, but might as well make a pre-set version to handle the heavy lifting.)

Code: Select all


DLight_Modulate (int MaxBrightness, int MinBrightness, int phase = 0, int BrightHoldTime = 0, int DarkHoldTime = 0, int CycleTime, color BrightColor, color DarkColor) {

/*
MaxBrightness: The highest value for the light's intensity
MinBrightness: The lowest value for the light's intensity

CycleTime: The time it takes the light to shift from bright to dark; in ticks.  Note that a cycle time of 30 will take 60 ticks to go from bright to dark and back to bright again.

BrightHoldTime: OPTIONAL. Upon reaching the brightest value, the light will hold steady for this amount of time; in ticks.  Default is zero, meaning it does not hold steady but will start dimming on the very next tick.
DarkHoldTime: OPTIONAL. Upon reaching the darkest value, the light will hold steady for this amount of time; in ticks.  Default is zero, meaning it does not hold steady but will start brightening on the very next tick.

Phase: OPTIONAL. Sets the start point for the light's cycle. Can be used to set a series of lights to modulate in sequence, ie, one light is bright when the other light is dark.  Value is in ticks, offsets the light's starting point.  Thus if a light's Cycle time is ten, a phase of 15 will start halfway between dark and light on its way to becoming light.  Note that the cycle starts on the "Bright Hold" portion of the cycle.

BrightColor: OPTIONAL.  The color of the light when it reaches its brightest value.  Default is the light's given value.
DarkColor: OPTIONAL. The color of the light when it reaches its darkest value.  Default is the light's given value.

*/

int tickCounter = 0;
int phaseCounter = 0;
float currVal = 0;

init {
	Phase = math.clamp(0, CycleTime * 2 + BrightHoldTime + DarkHoldTime);
	if (phase > BrightHoldTime) {
		phaseCounter = 2;
		Phase -= BrightHoldTime;
	}
	else {
		tickCounter = Phase;
		return;
	}

	if (phase > CycleTime) {
		phaseCounter++;
		Phase -= CycleTime;
	}
	else {
		tickCounter = Phase;
		return;
	}

	if (Phase > DarkHoldTime) {
		PhaseCounter++;
		Phase -= CycleTime;
	}

	tickCounter = Phase;

}

tick {

	tickCounter--;

	if (tickCounter <= 0) {

		phaseCounter--;

		if (phaseCounter <= 0) {
			phaseCounter = 4;
		}

		switch (phaseCounter) {

		case 4:	//Hold Bright

			tickCounter = BrightHoldTime;
			currVal = 1;
			break;

		case 2:	//Hold Dark

			tickCounter = DarkHoldTime;
			currVal = 0;
			break;

		default:

			tickCounter = CycleTime;
			break;	
		}

	}

	if (phaseCounter == 3 || phaseCounter == 1) {

		currVal = Math.InverseLerp(0, CycleTime, tickCounter);

		if (phaseCounter == 1) {
			currVal = 1f - currVal;
		}
	}

	DLight_SET( Math.Lerp(MinBrightness, MaxBrightness, currVal);
	DLight_Color( LerpColor(DarkColor, BrightColor, currVal);


}

}
...Then again, I wrote that assuming you would be able to set "phase" for each thing individually, and I don't think that can be done with ddf files. There might be some merit to setting a whole class of a thing with a given phase, but I was thinking of what you would want on an individual instance, and you could do things like make a row of lights that modulate in sequence.

User avatar
RUNSABER
Posts: 132
Joined: Sat Mar 14, 2015 3:10 pm

Re: ddf editing; looking for features

Post by RUNSABER »

You'd definitely have to hit up Coraline on that code, she says the lighting logic will get an overhaul in the next update or so. I do like those ideas you have, so vast yet limited only to how far you think DDF can stretch it. You might have to have several light defs to make alternating candle colors. There is modulate lighting ( DLIGHT.TYPE=MODULATE) and it works very well as a source of light and currently you can use it to simulate glowing surfaces such such lava, skies, etc. Give MODULATE a play around, along with LINEAR and ADD to see which of these work for ya in the meantime. DDF isn't too far from Decorate however I love being able to just write code now without much of s reference. Also, whatever code you write and want to share as a resource feel free to post it up. I'm looking to compile mass 3DGE resources and have them showcased and mod-friendly!
Official 3DGE64 Project Portal - Public Repository for 3DGE 64.

User avatar
Marscaleb
Posts: 89
Joined: Sat Jun 25, 2016 12:57 pm
Location: California or Utah
Contact:

Re: ddf editing; looking for features

Post by Marscaleb »

When I was testing the dynamic light options, I never found a way to make "modulate" actually glow or anything; it just looked like another way for it to calculate the fall-off rate.

User avatar
Marscaleb
Posts: 89
Joined: Sat Jun 25, 2016 12:57 pm
Location: California or Utah
Contact:

Re: ddf editing; looking for features

Post by Marscaleb »

RUNSABER wrote:You'd definitely have to hit up Coraline on that code, she says the lighting logic will get an overhaul in the next update or so.
Well then how do I summon Coraline?

I had asked about editing the dynamic lights on the SourceForge page (because that was the only official page for this project I could find anywhere) and she pointed me to the DDF files, and suggested that if I re-do the dynamic lights she might include my changes in the official release.
I've got a largely-acceptable version ready, except for the problem with the fire-based lights all blinking in unison.

If there is going to be an overhaul to the dynamic lights, I would just assume my changes be designed around the new version.

Sandstormer
Posts: 127
Joined: Sat Nov 22, 2014 3:12 pm

Re: ddf editing; looking for features

Post by Sandstormer »

I apologize for misunderstanding you. It seems that you are talking about editing the source code itself to change/extend the lighting within the engine as a whole, not merely changing the behavior of the lighting through DDF within a WAD file. I haven't hacked on 3DGE's source code in ages, so there isn't much I could do to help you in that department. Coraline is most likely following this thread and will provide a more acceptable answer soon enough. You could probably try PM'ing her, as well. Sorry for any inconvenience.

User avatar
Corbachu
Site Admin
Posts: 778
Joined: Fri Jun 08, 2012 11:22 am
Gender:
Contact:

Re: ddf editing; looking for features

Post by Corbachu »

Sorry! I've been pretty busy on 3DGE stuff, but first off:

Welcome to the forums Marscaleb! ;)

Second, what does your DDF dynamic light code look like, and what is the intended effect? I can take a look at it. . .
\(סּںסּَ` )/ۜ