Lantern "light halo" effect

Started by Laura Hunt, Thu 26/09/2019 09:13:11

Previous topic - Next topic

Laura Hunt

I still haven't begun to work on this because I don't have the art yet, but I'm trying to preemptively figure out how to go about it.

I want to achieve the classic effect where a character is carrying a lantern or torch and everything is dark except for whatever's inside the lantern's light radius. What would be the easiest way to do something like this? (By "easiest" I basically mean "without using Draw commands or dynamic sprites or other scary stuff" :-D).

I've seen that there's a Flashlight plugin, but I'm not sure if it does this or if it only handles a beam of light, or if it's even compatible with current versions of AGS. I've also searched around the forums but most of the more-or-less related threads I've found tend to be pretty ancient (2007-2009). I've probably missed something, though, because this is such a common effect that I'm sure lots of people here must have used it at some point.

Anyway, all I need for now is a hint in the right direction, and if I have any questions once I actually start working on it, I'll definitely come back to pester you all ;)

eri0o

The basic idea I can think is some sprite that is twice the size of your game camera, that's fully black, with a filled circle in the middle done in transparent color. Open GIMP, Aseprite, Graphics Gale, ... Your favorite drawing software that supports layers, and draw a layer that is fully black, and then draw a circle using the eraser. Save the file as a png and import on AGS with the option that preserves the alpha.

Now you need to move this along the character, supposing is the player character, you can do this in many ways. I would create a dummy character cLamp and set it's normal view to a view containing the sprite you just imported. If your light is directional, create a Sprite for each character loop and set it accordingly.

Now at game start, set the cLamp character z property to the height of your camera (this is, half that sprite you imported height). Set also this character to use manual baseline, and set the baseline to a number that is bigger than your biggest room height size, you can also do this using the properties on the Editor.

Now create a boolean variable for you to know the lamp is on.

Create a new module Script, and there, at repeatedly_execute_always, check if the lamp is on, and if it's , set cLamp.Room to match your player Room, and just set cLamp.x and cLamp.y to match the target character (probably the player) x and y position.

Laura Hunt

That looks like a very doable approach with my very basic scripting skills (nod) And I wouldn't even need to check if the lamp is on, because the only time this would happen would be in a specific room.

Thanks a lot for the help!

eri0o

Oh, so the repeatedly_execute_always can be in the room itself, and whatever I said to do at game_start can be on the room load before fadein function. :)

Good luck, share a gif once it works :D

Laura Hunt

Quote from: eri0o on Thu 26/09/2019 13:17:52
Oh, so the repeatedly_execute_always can be in the room itself, and whatever I said to do at game_start can be on the room load before fadein function. :)

Good luck, share a gif once it works :D

Perfect, thanks! ;-D

I'll definitely share the results and in fact I plan on opening a thread in the "Games in production" subforum once we have some more stuff. The "problem" right now is that the game is divided into several "acts" or "chapters", each one with different protagonists, plot, etc (kind of like a horror anthology), and because we're working in order, right now only the first one is 95% finished whereas the others are barely fleshed out art-wise. This lantern effect is planned for the third act, so it will still take a while to have anything to show for it! :)


Cassiebsg

Also remember that there's a late_repeatedly_execute_always , if the rep_exe_always is acting up.  ;)
There are those who believe that life here began out there...

Laura Hunt

Quote from: Cassiebsg on Thu 26/09/2019 15:03:52
Also remember that there's a late_repeatedly_execute_always , if the rep_exe_always is acting up.  ;)

I never have had to use it so far, but it's a good tip to keep in mind ;)

Crimson Wizard

Quote from: Laura Hunt on Thu 26/09/2019 16:34:40
Quote from: Cassiebsg on Thu 26/09/2019 15:03:52
Also remember that there's a late_repeatedly_execute_always , if the rep_exe_always is acting up.  ;)

I never have had to use it so far, but it's a good tip to keep in mind ;)

The difference as explained in the manual:

QuoteIn a nutshell, if you need to do something right before game state changes, use repeatedly_execute_always, if you need to do something right after game state has changed, use late_repeatedly_execute_always.

Functions are called like this:
* repeatedly_execute_always
* game updates itself
* late_repeatedly_execute_always
* game draws itself

Laura Hunt

Quote from: Crimson Wizard on Thu 26/09/2019 16:59:53

The difference as explained in the manual:

QuoteIn a nutshell, if you need to do something right before game state changes, use repeatedly_execute_always, if you need to do something right after game state has changed, use late_repeatedly_execute_always.

Functions are called like this:
* repeatedly_execute_always
* game updates itself
* late_repeatedly_execute_always
* game draws itself

Yeah I got that from reading the manual, but I can't quite wrap my head around when you would need to use one or the other. But I'm totally a hands-on learner, so I find it much easier to grasp concepts like these when the opportunity to put them into practice presents itself.

So for example, if I'm listening in repeatedly_execute_always for the player stepping on a region (in order to change the sound of their footsteps), is this correct, or should I be doing in it in late_repeatedly_execute_always, i.e., after the game state has been updated with the player's new position? Or does it not matter in this case?

(This is starting to veer off-topic, but if I learn something new it'll be worth it!)


eri0o

I do a hack of changing the character normal view to another that's identical but with different sounds. I don't remember if it's the region or hotspot, but there's a place to set the view - I didn't had many cases I needed and have set it for the project a long time ago.

Laura Hunt

Quote from: eri0o on Thu 26/09/2019 18:10:02
I do a hack of changing the character normal view to another that's identical but with different sounds. I don't remember if it's the region or hotspot, but there's a place to set the view - I didn't had many cases I needed and have set it for the project a long time ago.

Ah, that's clever! But no worries, the way I'm doing it now works fine :) I do notice that sometimes there's a veeeery tiny delay or a sound fails to change in the first step, which is why I was wondering that maybe late_rep_ex would be an even better place to do it... Hmmm... guess I should just try!

Cassiebsg

I've used it before.
I had this object my character had in hand.
If I placed the draw function in rep_exe_always, it would draw the object and then jump to the correct place. Using the late_ it calculated accordingly to where the character was and then draw it in the correct place. So in other words, if you notice a slight "blink" or "whatever jumping" after it should already be in place, move it to late_ .  ;)
There are those who believe that life here began out there...

Laura Hunt

Quote from: Cassiebsg on Thu 26/09/2019 18:49:16
I've used it before.
I had this object my character had in hand.
If I placed the draw function in rep_exe_always, it would draw the object and then jump to the correct place. Using the late_ it calculated accordingly to where the character was and then draw it in the correct place. So in other words, if you notice a slight "blink" or "whatever jumping" after it should already be in place, move it to late_ .  ;)

Alright! I'll have to give it a try :)

Crimson Wizard

I think you should be using late_ function if you must sync something to some game object or property. If you do not rely on other game objects then it's safe to code in a regular rep_exec.

Also, you should be using regular rep_exec_always if your aim is to affect the game's update in this frame, then you obviously should do that before that update happens.

cat

#14
Have a look at Cave of Avarice.

At first I tried to use a module, but the performance was bad and it couldn't do alpha channel.
That's why I wrote it myself.

I use one GUI for the lamp shine and another GUI that is black except for a circle with a scattered outline.
In repeatedly_execute_always I update the location of both GUIs to match the character and I also change the graphic of each GUI to another random graphic every 10 frames to create a flickering effect.
I also coded a special handling so the overhotspot label and clicks only work within a square around the player.

Cassiebsg, I definitely need to follow your posts on the techincal boards - you know so many obscure functions like late_repeatedly_execute_always that I've never heard about.

Laura Hunt

Quote from: Crimson Wizard on Thu 26/09/2019 19:23:17
Also, you should be using regular rep_exec_always if your aim is to affect the game's update in this frame, then you obviously should do that before that update happens.

Ah, that makes sense. Then I'm probably doing it right. Still want to see what happens if I change the function over to late_rep_exec. For science!  ;-D

Quote from: cat on Thu 26/09/2019 20:28:51
Have a look at Cave of Avarice.

At first I tried to use a module, but the performance was bad and it couldn't do alpha channel.
That's why I wrote it myself.

I use one GUI for the lamp shine and another GUI that is black except for a circle with a scattered outline.
In repeatedly_execute_always I update the location of both GUIs to match the character and I also change the graphic of each GUI to another random graphic every 10 frames to create a flickering effect.

Thanks, cat! My first thought was indeed to do something with GUIs, so I'm really curious about your method. I'll take a look at the game this weekend :)

Quote from: cat on Thu 26/09/2019 20:28:51
I also coded a special handling so the overhotspot label and clicks only work within a square around the player.

Ah crap! True, I hadn't thought of that! Well, that'll be one more thing to worry about then.


TheManInBoots

#16
Quick tip:

Instead of using an eraser to "carve out" the hole in the black graphic that creates the shadow effect (or the black gui), when using gimp, you could do this:

Select the Circle area with the Circle tool, while having the "Feather Edges" Option ticked and adjusted to your needs.
Then delete the selected area.
This will create a smooth transition between the dark and lit area, and will look way more realistic.
Save as png, done!

Laura Hunt

Quote from: TheManInBoots on Tue 01/10/2019 21:14:59
Quick tip:

Instead of using an eraser to "carve out" the hole in the black graphic that creates the shadow effect (or the black gui), when using gimp, you could do this:

Select the Circle area with the Circle tool, while having the "Feather Edges" Option ticked and adjusted to your needs.
Then delete the selected area.
This will create a smooth transition between the dark and lit area, and will look way more realistic.
Save as png, done!

Well, the artist takes care of these things, but even I know about the feather edges in Photoshop (laugh) Thanks though!

cat, I'm sorry I still haven't been able to check out Cave of Avarice. The artist kicked into gear this week after two months of being completely tied up in a paying gig and not being able to work on our game at all, so I've received a TON of material to work with and I haven't had time to work on anything else. But I haven't forgotten about it!


TheManInBoots

The feathering option is not the main part of my idea. It's just to exemplify how it can be implemented. The main value of my idea is to use transitioning borders for the halo light spot, which creates an alluringly realistic effect. It's small details like that that turn a game from good or ok to awesome!

Laura Hunt

Apologies for necroing this thread, but I promised I would report back when I finally got around to implementing this and I'm a woman of my word, so I'm very pleased to say that everything is working perfectly so far :)



Obviously this is a super rough prototype and there's still lots of stuff to polish such as the edges of the light circle (and totally unrelated, those shelves' baselines in iso perspective are going to be the death of me). But thanks to everybody who chimed in with suggestions and tips! It feels so great to finally get around to implementing it in-game.

SMF spam blocked by CleanTalk