MODULE: Day/Night Cycle (+Seasons)

Started by Snarky, Sun 05/01/2014 20:25:44

Previous topic - Next topic

Snarky

This is a quick little module for having dynamic time in your game, with day/night-cycles and seasons. The module takes care of the timekeeping and working out what that means in terms of time-of-day, season, etc. It doesn't actually make it dark at night or add flowers to your backgrounds in the spring, but the demo game shows how it can be used to create such effects. (Though you'll have to imagine the seasons.)

Simple to use:
Spoiler
Code: AGS

// Setup/start
{
  DayNight.SetTime(1, 4, 55);
  DayNight.SetTimeSpeed(40);
  DayNight.SetTimeRunning(true);
}

// Display current time
{
  lblStatus.Text = String.Format("%s, Day %d (%s) %02d:%02d",
                                  DayNight.GetSeasonName(), 
                                  DayNight.GetDay(),
                                  DayNight.GetTimeOfDayName(),
                                  DayNight.GetHour(),
                                  DayNight.GetMinute());
}

// Add an overlay to make the screen darker at night
{
  DayNight_TimeOfDay timeOfDay = DayNight.GetTimeOfDay();
  if(timeOfDay == DayNight_Night)
  {
    gNightOverlay.Visible = true;
  }
}
[close]
Downloads:
v 1.2.0
Day/Night module
Day/Night demo game (AGS 3.3 beta project)
Demo game EXE

v 1.0.1
Day/Night module
Day/Night demo game (AGS 3.3 beta project)
Demo game EXE

Screenshots:

The same screen at night, daybreak and daytime. Precise effect up to game creators.


Demo UI to set the time and clock speed

Version info:
1.2.0 Added year count, simplified and generalized API, optimized internally. Demo game set to 800x600
1.0.1 Fixed bug in demo game, improved responsiveness of notifications when setting time of day manually
1.0.0 Initial release

Grim

Nice module, but I got s crash when setting speed to 1 and running it for a while. (didn't save the error message but it was sometime in the afternoon;) and about transparency values having to be between 0 and 100 )

Snarky

Ah yes, a little calculation error in the demo game. Should be fixed now. Thanks for the bug report!

Imc7r

Hello, I want to use it. It didn't need a sunrise light but it's even better like that. Im not sure how to use it, besides importing the script, do I need to add this piece of code below to the global script like when the game starts or where?

Code: ags
// Setup/start
{
  DayNight.SetTime(1, 4, 55);
  DayNight.SetTimeSpeed(40);
  DayNight.SetTimeRunning(true);
}


And speaking of the night, I tested in GIMP, basically a RGB 0,0,16 is the darkness I need where I can change opacity to 75 of 100, the Tint Screen code that makes it like that only allows 50% and that's not enough to make dark enough. So which one should I change to achieve the 75 of 100 effect? Do I need to add this code and where:


Code: ags
// Add an overlay to make the screen darker at night
{
  DayNight_TimeOfDay timeOfDay = DayNight.GetTimeOfDay();
  if(timeOfDay == DayNight_Night)
  {
    gNightOverlay.Visible = true;
  }
}

Snarky

#4
Quote from: Imc7r on Mon 07/05/2018 18:11:18
Hello, I want to use it. It didn't need a sunrise light but it's even better like that. Im not sure how to use it, besides importing the script

Hi Imc7r,

I would recommend you to take a look at the demo game to see how the module can be used.

Quotedo I need to add this piece of code below to the global script like when the game starts or where?

Code: ags
// Setup/start
{
  DayNight.SetTime(1, 4, 55);
  DayNight.SetTimeSpeed(40);
  DayNight.SetTimeRunning(true);
}

Yes, you need something like that to initialize the module. Whether it should be in game_start() really depends on your game. Probably in most cases you wouldn't actually start the clock until some specific point in the game (e.g. after an intro cutscene), so that's where you should call SetTimeRunning().

QuoteAnd speaking of the night, I tested in GIMP, basically a RGB 0,0,16 is the darkness I need where I can change opacity to 75 of 100, the Tint Screen code that makes it like that only allows 50% and that's not enough to make dark enough. So which one should I change to achieve the 75 of 100 effect?

There are a few different ways to create a night effect (tinting, overlays, palette effects, alternate backgrounds...). The demo game just uses the simplest possible one: an overlay (in the form of a full-screen, non-clickable GUI). In your case, I would create an image the size of your game resolution, fill it with 0,0,16 blue, and import it into AGS as a sprite. Create a GUI called gNightOverlay. Make it the size of your screen with x,y coordinates 0,0. Set it to non-clickable and its background to that sprite.

Once you've done that, you just need to display the GUI at 75% opacity when it's night, which...

QuoteDo I need to add this code and where:

Code: ags
// Add an overlay to make the screen darker at night
{
  DayNight_TimeOfDay timeOfDay = DayNight.GetTimeOfDay();
  if(timeOfDay == DayNight_Night)
  {
    gNightOverlay.Visible = true;
  }
}

Yes. You also need to add a line gNightOverlay.Transparency = 25; so that it's at 75% opacity. I would probably make a function for it, say drawNightOverlay(), and call it from repeatedly_execute_always(). That's how it's done in the demo game.

Once you've got that working, you can take a look at the drawNightOverlay() function there (it's in the GlobalScript) to see how you can also fade the darkness in and out during evening and morning. But I would take it one step at a time. If you can make it be dark at night and light during the day, that's a great first step.

If you have trouble defining and calling functions, I recommend you go through the tutorial and intro to scripting in the manual. Good luck!

Imc7r

#5
Thanks.. I decided to use even simpler version as you said creating the GUI with image and setting it in function repeatedly_execute_always() then since it didn't work to set myGUI.transparency to myGUI.transparency--; to reduce to 25 since the value did not want to decrease, I used a variable even float to delay the count from 100 to 25 for even slower than 1 second, then it worked like Fade quite smooth enough.

Spoiler
Code: ags

bool nightFall;
float lightTransparency;
float durationDay;
float durationNight;

function repeatedly_execute_always() {
  
  if (FloatToInt(durationDay, eRoundNearest) < 200 && nightFall == false )
  {
    durationDay++;  
    gNightOverlay.Visible = false;
    lightTransparency = 100.00;
  }
  
  if (FloatToInt(durationDay, eRoundNearest) == 200)
  {
    gNightOverlay.Visible = true;
    
    //0.01 is around 3 mins of transition to full darkness
    lightTransparency = lightTransparency - 1.00;

    if (lightTransparency > 25.0) { gNightOverlay.Transparency = FloatToInt(lightTransparency, eRoundNearest); }
  }
  
  if (gNightOverlay.Transparency == 26)
  {
    durationDay = 0.0;
    durationNight++;
    nightFall = true;
  }
  
  if (FloatToInt(durationNight, eRoundNearest) == 200)
  {
    lightTransparency = lightTransparency + 1.00;
    if (lightTransparency < 100.0) { gNightOverlay.Transparency = FloatToInt(lightTransparency, eRoundNearest); }
  }

  if (gNightOverlay.Transparency == 100 && nightFall == true)
  {
    durationDay++;
    durationNight = 0.0;
    nightFall = false;
  }
  
}
[close]

Vincent

Offtopic question: what would be the best way to implement the months too into your module? I know that we talked about this before, I would like to do it with their actual lengths at the moment. However, my purpose to keep track of the month lenghts would be to display properly their name when the 'dayOfMonth' change, any suggestion on how to do that?

SMF spam blocked by CleanTalk