Recent posts

#1
In preparation for sharing my game on Itch.io, I had Uncle Conroy do a little pitch for the game to drum up enthusiasm!
#2
Okay.  Using the code provided by Khris, I was able to get the tint working.  Many thanks, Khris, Crimson, and Snarky for the guidance on that issue.

The Time Of Day is still wonky, so I'm moving back on to that now.


The above video demonstrates that the screen tint is indeed following the Time Of Day now, but that Time Of Day is out of whack with Time.
#3
Apologies about the reply thing.  I had no idea that was a problem, I was just trying to be clear about what I was replying to.  I don't know what "shotgun debug" means, but I assure you I am trying my best to understand what's happening and fix it.  It seems I am misunderstanding quite a bit though.  Apologies.  I am not a very experienced programmer.

I think I understand now what Snarky and CW were saying about how I was doing the tint wrong.  I didn't understand at the time it was first expressed, because I had only just learned that dynamic sprites existed and wasn't able to understand the explanation.  I think I do now, though I haven't tried putting it into practice yet because I am first trying to fix the Time Of Day problem which is also occurring.  I trust that the advice you and others have given me on the tint issue is solid, I'm just currently banging my head against the other problem which I thought would be easier and more pressing to sort out.


The above video is a demonstration of what is going on with the Time Of Day display.    I'm trying to take this one problem at a time though, because I'm not a very experienced programmer.

Here is my updated code in which I put the Time label update in its own function (called at game start and whenever Time Passes), which allowed me to stop calling Update Screen whenever time passes.

HEADER:
Code: ags
// new module header

#define MINUTES_PER_MINUTE 1 // in-game time is 10 times faster

enum TimeOfDay {
 eTODMorning = 0, eTODMidday = 1, eTODEvening = 2, eTODNight = 3
};

import void TimePasses(int minutes);

import int _minutes; //= 600;

SCRIPT:
Code: ags
// new module script

// game starts at 10:00 on day 1
int _minutes = 600;
export _minutes;
int _day = 1;
TimeOfDay _timeOfDay = eTODMorning;
export _timeOfDay;

// background tint stuff
DynamicSprite* bgSprite;
DrawingSurface *bgSurface;

void UpdateTimeLabel() {
    // display time on label
    int hours = _minutes / 60;
    int minutes = _minutes % 60;
    lblTime.Text = String.Format("%02d:%02d", hours, minutes);
    Display("Displaying time on label.");
}

void UpdateScreen() {
    // tint screen,  update label,  etc.
    // display TimeOfDay
    if (_timeOfDay == eTODMorning) {
      //TimeOfDay = eTODMorning;
      lblTimeOfDay.Text = String.Format("Day %d: Morning",  _day);
      //Tint characters & objects
      SetAmbientTint(64, 64, 0, 50, 75);
      //Tint room background
      bgSprite = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
      bgSprite.Tint(64, 64, 0, 50, 75);
      bgSurface = Room.GetDrawingSurfaceForBackground();
      bgSurface.DrawImage(0, 0, bgSprite.Graphic);
      bgSurface.Release();
      bgSprite.Delete();
    }
    else if (_timeOfDay == eTODMidday) {
      //TimeOfDay = eTODMidday;
      lblTimeOfDay.Text = String.Format("Day %d: Mid-Day",  _day);
      //Tint characters & objects
      SetAmbientTint(0, 0, 0, 0, 100);
      //Tint room background
      bgSprite = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
      bgSprite.Tint(0, 0, 0, 0, 100);
      bgSurface = Room.GetDrawingSurfaceForBackground();
      bgSurface.DrawImage(0, 0, bgSprite.Graphic);
      bgSurface.Release();
      bgSprite.Delete();
    }
    else if (_timeOfDay == eTODEvening) {
      //TimeOfDay = eTODEvening;
      lblTimeOfDay.Text = String.Format("Day %d: Evening",  _day);
      //Tint characters & objects
      SetAmbientTint(0, 0, 128, 50, 75);
      //Tint room background
      bgSprite = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
      bgSprite.Tint(0, 0, 128, 50, 75);
      bgSurface = Room.GetDrawingSurfaceForBackground();
      bgSurface.DrawImage(0, 0, bgSprite.Graphic);
      bgSurface.Release();
      bgSprite.Delete();
    }
    else {
      //TimeOfDay = eTODNight;
      lblTimeOfDay.Text = String.Format("Day %d: Night",  _day);
      //Tint characters & objects
      SetAmbientTint(0, 0, 128, 75, 50);
      //Tint room background
      bgSprite = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
      bgSprite.Tint(0, 0, 128, 75, 50);
      // Now copy it back to the background
      bgSurface = Room.GetDrawingSurfaceForBackground();
      bgSurface.DrawImage(0, 0, bgSprite.Graphic);
      // Clean up
      bgSurface.Release();
      bgSprite.Delete();
    }
    
}

void TimePasses(int minutes) {
  Display("Time passes.");
  _minutes += minutes; 
  // if end of day was reached
  if (_minutes >= 1440) {
    _minutes -= 1440;
    _day++;
  }
  //UpdateScreen();
  UpdateTimeLabel();
  
  TimeOfDay now = ((_minutes + 240) / 360) % 4;
  if (now != _timeOfDay) {
    _timeOfDay = now;
    UpdateScreen();
  }
}

function game_start() {
  //UpdateScreen();
  UpdateTimeLabel();
  lblTimeOfDay.Text = String.Format("Day %d: Morning",  _day);
}


int _frames;
function repeatedly_execute() {
    //Display("Repeatedly exceute.");  
    
    if (lblTime.Text == "") {
      UpdateScreen();
    }

    // increase by one
    _frames++;
    //Display("Frame increased.");
  
    // if a minute of IRL time has passed
    if (_frames >= GetGameSpeed() * 60) {
      _frames -= GetGameSpeed() * 60;
      TimePasses(MINUTES_PER_MINUTE); // advance game time
    }
}
#4
Advanced Technical Forum / Re: Day/Night Cycle, Time of D...
Last post by Khris - Yesterday at 23:44:25
First of all, please use the Reply button below the last post. There's no need to duplicate my entire post in a reply that is directly below it anyway.

As Snarky and CW have tried to explain, the stacking is not caused by calling UpdateScreen too often; your version was simply stacking the tinting because it didn't use a fresh copy of the background image.
My version will never stack the tinting regardless of how often it is called because it makes a copy of the background when the room is loaded, then makes a copy of that copy which is then tinted.

My code only calls UpdateScreen() a maximum of four times per day: at 4:00, at 10:00, at 16:00 and at 22:00.
(At least it's supposed to; I didn't test any of this)

Using a separate function seems kind of pointless since the tint and label will change at the exact same time. Don't shotgun debug; try to understand what's happening and fix it.
#5
Quote from: Khris on Yesterday at 23:13:27You added a call to UpdateScreen() to TimePasses, why? The room background is only supposed to change when the minutes move into a new time of day range, right?

Anyway, the math isn't that complicated. I'm adding 240 (4 hours) so the morning starts at 4. Then I divide by 360 (6 hours) to get the four different values. Near the end of the day, this will result in 4, so I do mod 4 to roll it over to 0.

Code: ags
DynamicSprite* backup;

// AGS will call this each time a room is about to fade in
function on_event(EventType event, int data) {
  if (event == eEventEntersRoomBeforeFadein) backup = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
}

void UpdateScreen() {

  // make a copy of the backup so the tinting doesn't stack
  DynamicSprite* bgSprite = DynamicSprite.CreateFromExistingSprite(backup.Graphic);

  // time of day specific code
  switch (_timeOfDay) {
  case eTODMorning:
    lblTimeOfDay.Text = String.Format("Day %d: Morning",  _day);
    SetAmbientTint(64, 64, 0, 50, 75);
    bgSprite.Tint(64, 64, 0, 50, 75);
    break;
  case ...
    ...
  }
  // end of time of day specific code

  DrawingSurface* bgSurface = Room.GetDrawingSurfaceForBackground();
  bgSurface.DrawImage(0, 0, bgSprite.Graphic);
  bgSurface.Release();
  bgSprite.Delete();
}

Since I was advised to move my screen updates (including screen tint and label text) out of the repeatedly_execute() function, I moved them into the Update Screen() function instead.  As a result, they were not always being updated when Time Passes, so I had Time Passes update the screen whenever it runs, which is now causing the tint pile-up.  I am thinking now that maybe I should make a separate function for the Time label to update.
#6
Advanced Technical Forum / Re: Day/Night Cycle, Time of D...
Last post by Khris - Yesterday at 23:13:27
You added a call to UpdateScreen() to TimePasses, why? The room background is only supposed to change when the minutes move into a new time of day range, right?

Anyway, the math isn't that complicated. I'm adding 240 (4 hours) so the morning starts at 4. Then I divide by 360 (6 hours) to get the four different values. Near the end of the day, this will result in 4, so I do mod 4 to roll it over to 0.

Code: ags
DynamicSprite* backup;

// AGS will call this each time a room is about to fade in
function on_event(EventType event, int data) {
  if (event == eEventEntersRoomBeforeFadein) backup = DynamicSprite.CreateFromBackground(GetBackgroundFrame());
}

void UpdateScreen() {

  // make a copy of the backup so the tinting doesn't stack
  DynamicSprite* bgSprite = DynamicSprite.CreateFromExistingSprite(backup.Graphic);

  // time of day specific code
  switch (_timeOfDay) {
  case eTODMorning:
    lblTimeOfDay.Text = String.Format("Day %d: Morning",  _day);
    SetAmbientTint(64, 64, 0, 50, 75);
    bgSprite.Tint(64, 64, 0, 50, 75);
    break;
  case ...
    ...
  }
  // end of time of day specific code

  DrawingSurface* bgSurface = Room.GetDrawingSurfaceForBackground();
  bgSurface.DrawImage(0, 0, bgSprite.Graphic);
  bgSurface.Release();
  bgSprite.Delete();
}
#7
Competitions & Activities / Re: MAGS September "The Broad-...
Last post by Stupot - Yesterday at 23:04:14
Quote from: EmmaGundersen on Sun 14/09/2025 20:10:17Hm. Once again I see a fun MAGS theme but only after half the month has already passed :/
If I can find the time I'll try to throw together a short entry.
If it helps, I was almost a week late opening this round, so you're not as far behind as you might think.
#8
Quote from: Snarky on Yesterday at 22:46:32
Quote from: GildedSpaceHydra on Yesterday at 21:56:30The screen is being tinted when time passes.  Unfortunately the screen is tinted WHENEVER time passes, so advancing the clock by one minute causes Time Of Day to change and thus the tint.

I don't think the problem is that the time of day changes whenever you advance the clock. I think what's happening is that the screen is being tinted every time you call UpdateScreen, and you're doing that every time you call TimePasses (line 88).

The time of day calculation is not very transparent, but it's dividing the current _minutes value by 360, so it will only change every 6 hours.

And as CW points out, you're doing the tinting wrong, causing the effect to stack. (Instead of drawing the tint onto the background I would suggest just covering it with a semi-transparent Overlay or GUI.)

(I'm more and more thinking that maybe you should just use my module.)

Time Of Day (at least as displayed on the status bar) is changing when time advances, though I haven't sorted out the logic of why it's changing to what it's changing to. 

I see what you're saying about the tint being compounded whenever time passes though and will try to work on that.  I'll consider the overlay and GUI options as well; I had just read some other threads on this kind of effect where people had said they didn't get the results they were after using a GUI and that dynamic sprites had worked better for them.  These options may be fine for me though.  I'll experiment with it and see what I can come up with. 

Thanks!
#9
Quote from: Crimson Wizard on Yesterday at 22:28:13
Quote from: GildedSpaceHydra on Yesterday at 21:56:30Additionally, every time the tint changes, it seems to stack (like maybe the previous DynamicSprite isn't being removed before the new tint is added: the more time advances, the darker the screen gets).

That is what I was referring to earlier:

QuoteYou must make a copy of original background when you enter the room and save it in a DynamicSprite variable for using in drawing, because next time you call "DynamicSprite.CreateFromBackground" it will return a already modified background.

It should go like this:
1. Store and keep a copy of original background in a separate dynamic sprite.
2. When updating background:
 a) make a copy of dynamic sprite which has original bg in it
 b) tint the copy
 c) paste the tinted copy to room background.

Ah, ok!  That makes sense.  I read the previous post, but I suppose I didn't fully understand it  as dynamic sprites were a brand new concept to me at the time, but I get what you're saying now.  I'll go back to the documentation and see if I can figure out how to do that.  Thanks much!
#10
Advanced Technical Forum / Re: Day/Night Cycle, Time of D...
Last post by Snarky - Yesterday at 22:46:32
Quote from: GildedSpaceHydra on Yesterday at 21:56:30The screen is being tinted when time passes.  Unfortunately the screen is tinted WHENEVER time passes, so advancing the clock by one minute causes Time Of Day to change and thus the tint. 

I don't think the problem is that the time of day changes whenever you advance the clock. I think what's happening is that the screen is being tinted every time you call UpdateScreen, and you're doing that every time you call TimePasses (line 88).

The time of day calculation is not very transparent, but it's dividing the current _minutes value by 360, so it will only change every 6 hours.

And as CW points out, you're doing the tinting wrong, causing the effect to stack. (Instead of drawing the tint onto the background I would suggest just covering it with a semi-transparent Overlay or GUI.)

(I'm more and more thinking that maybe you should just use my module.)
SMF spam blocked by CleanTalk