What is the best way to code a night and day system?

I am making a game where you move around a town either day or night. The character locations and interactions change from night to day. An example would be the town librarian who is at her job during the day and at the bar at night. And her dialogue and actions change between locations.
So first question, how to I code the day-night change? I don't want it to be based on a timer so I was hoping to do a number of turns. Second, when it comes to the character's coding and location changes between locations, should I do it be creating separate objects for the characters with one for the night and one for day, and when the time shifts for example when it is night, the day character is moved to a room while the night object is moved from that room to its assigned location? Or can someone think of a better way?


If you just want day and night (and don't want to worry about what time it is), you could just use a turnscript to count turns. You could set it up as a simple framework, so that adding new objects to the system is as simple as possible.

I'd suggest making a turnscript called daynight, doing something like this:

firsttime {
  this.turncount = 0
  this.mode = "day"
}
otherwise {
this.turncount = (this.turncount + 1) % 28
if (this.turncount = 0) {
  if (this.mode = "day") {
    this.mode = "night"
    msg ("The sun sets")
  }
  else {
    this.mode = "day"
    msg ("The sun rises")
  }
}
if (this.turncount = 0) {
  foreach (object, AllObjects()) {
    if (HasObject (object, this.mode + "version")) {
      alternate = GetObject (object, this.mode + "version")
      alternate.visible = object.visible
      alternate.parent = object.parent
      object.parent = null
    }
    if (HasBoolean (object, this.mode + "visible")) {
      object.visible = GetBoolean (object, this.mode + "visible")
    }
    if (HasObject (object, this.mode + "location")) {
      object.parent = GetObject (object, this.mode + "location")
    }
    if (HasScript (object, this.mode + "script")) {
      do (object, this.mode + "script")
    }
  }
}

In this example, it will change every 28 turns… you can just change the number for a longer or shorter cycle.

This would make moving objects around easier. You can give any object a few attributes to make it change when the day/night changes.

  • If an object has an attribute dayversion (or nightversion), those objects will swap places when it becomes day (or night)
  • If an object has an attribute dayvisible set to false, the object will be hidden when the sun comes up. If it has an attribute nightvisible set to true, it will become visible again when it becomes night.
  • If an object has an attribute nightlocation which points to a room, it will automatically be moved to that room at night.
  • If an object has a script attribute dayscript, that script will be run whenever it becomes day. You can use this to change any other details about the object.

So if an NPC just moves to a different location at night, you could just give them daylocation and nightlocation attributes, and not worry about it. If there's an NPC whose house you can't get into (so you only see them during the day), you could use dayvisible and nightvisible to make them go away. If an object only has a couple of things that need to be changed, you could use dayscript and nightscript to make those changes.

And if they behave completely differently, it might be easier to have two objects for the day and night versions. Then the NPC objects for the day would have a nightversion attribute which refers to the night version, and vice versa. When it becomes night, the night version will appear and the day version will disappear automatically.

For some simple objects, you might not need to use any of this. For example, in a factory room, you could have the description like:

There are machines everywhere. {if daynight.mode=day:Workers scurry in all directions, and the place is a hive of activity.}{else:The beams creak softly in the darkness, machines standing idle while they wait for the morning workers to arrive.}

Hope that's helpful.


Gng

I have an object called "timers" and for every exit or action or fight I have:

timers.time = timers.time + integer

The integer is specific for each action so I have a lot of flexibility.
And then after time reaches a certain number in changedtime attribute:

If (timers.time > 1200){
  timers.partofday = 5
//night
// msg: it's night etc. etc. 
}
Else if (timers.time > 1020){
  timers.partofday = 4
//evening
}
Else if (timers.time > 600){
  timers.partofday = 3
//noon
}
Else if (timers.time > 360){
  timers.partofday = 2
//morning
}
Else {
  timers.partofday = 1
//midnight
}

In each object description I have different scripts based on timers.partofday


Thanks I have two more questions for Mrange. Is it possible to disable and enable the turn script through code? Because certain interactions in the came I don't want to move time regardless of turns.
Second, how can I manually switch time of day by code? That would be useful for say adding a sleep function to the character so people don't have to wait to get the interactions they seek?


Is it possible to disable and enable the turn script through code? Because certain interactions in the came I don't want to move time regardless of turns.

Yes. You can use:

  • daynight.enabled = true
  • daynight.enabled = false

These will just stop the timer from advancing.

Second, how can I manually switch time of day by code? That would be useful for say adding a sleep function to the character so people don't have to wait to get the interactions they seek?

OK… this is slightly awkward given the way I coded that example (trying to keep it simple).

If you just want to skip ahead to dawn, it would simply be:

daynight.turncount = -1

Which forces a day/night transition this turn.

If you want to skip to some time that isn't a transition between modes (like three turns before dawn), you would have to run the script manually to force a transition. For example, to sleep until the middle of the day:

if (daynight.mode = "night") {
  daynight.turncount = -1
  do (daynight, "script")
}
daynight.turncount = 14

Or if you wanted some action to take more time than usual, you could include this in a command/verb:

for (i, 1, 5) {
  do (daynight, "script")
}

which just causes the timer to go forward 5 turns, handling dawn or dusk if necessary.

Does one of those do what you need?
If you're after something more advanced, it's not too hard to make a full time system (so that you can do things like waiting until a certain time). The one I write here was just intended as a simplified version, which doesn't provide too much functionality.


And a little optimisation in case you're using the web editor, to make NPCs easier to handle. In your start script, you could put:

foreach (obj, AllObjects ()) {
  if (EndsWith (obj.name, "_day")) {
    night = GetObject (Replace (obj.name, "_day", "_night"))
    if (not night = null) {
      night.dayversion = obj
      obj.nightversion = night
    }
  }
}

With that, you could create objects named, (for example) barman_day and barman_night and they will automatically switch places without having to add the attributes manually.


This topic is now closed. Topics are closed after 14 days of inactivity.

Support

Forums