Repository: evennia/evennia

Issue:
[BUG - Develop] `schedule` isn't scheduling properly
#### Describe the bug
When using `evennia.utils.gametime.schedule` to schedule a recurring event, it happens at the correct time for the first iteration and then continues repeating at intervals of that initial delay, instead of the scheduled interval.

#### To Reproduce
Steps to reproduce the behavior:
1. Schedule an hourly task starting in a few minutes, e.g. if the gametime is 10:40, set it for `min=45, sec=0`
2. Wait for it to trigger.
3. Check the time until the second iteration (which should be in one gametime hour).
4. See error

#### Expected behavior
It should trigger as it does with the initial delay the first time, but then continue further iterations at the scheduled time.

#### Develop-branch commit
f093c8bcb

#### Additional context
My original schedule line in `py`: `schedule(clock_chime, repeat=True, min=45,sec=0)`

Shortly after that initial schedule:
```
+-------+----------+----------+--------+------+------+-----------+-----------+
| dbref |      obj |      key | intval | next | rept | typeclass |      desc |
+~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~+~~~~~~+~~~~~~+~~~~~~~~~~~+~~~~~~~~~~~+
|       |          |          |        |      |      |           | A gametim |
|    #9 | <Global> | TimeScri | 147.54 | 130s |  -/- | TimeScrip | e-sens[.. |
|       |          |       pt |   1335 |      |      |         t |        .] |
+-------+----------+----------+--------+------+------+-----------+-----------+
```
Right after it triggered the first time:
```
+-------+----------+----------+--------+------+------+-----------+-----------+
| dbref |      obj |      key | intval | next | rept | typeclass |      desc |
+~~~~~~~+~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~+~~~~~~+~~~~~~+~~~~~~~~~~~+~~~~~~~~~~~+
|       |          |          |        |      |      |           | A gametim |
|    #9 | <Global> | TimeScri | 147.54 | 144s |  -/- | TimeScrip | e-sens[.. |
|       |          |       pt |   1335 |      |      |         t |        .] |
+-------+----------+----------+--------+------+------+-----------+-----------+
```
I waited for a couple of minutes to confirm that it would successfully trigger, which it did, and then looped on that initial interval again.


Discussion:
It looks like `TimeScript` - the script class used by `schedule` - wasn't updated with the Scripts rewrite and is still restarting itself with the now obsolete `.restart` method. This should be fixable by changing `TimeScript.at_repeat` to use `self.start(interval=seconds, force_restart=True)` instead.

Resolving patch:
diff --git a/evennia/contrib/base_systems/custom_gametime/custom_gametime.py b/evennia/contrib/base_systems/custom_gametime/custom_gametime.py
--- a/evennia/contrib/base_systems/custom_gametime/custom_gametime.py
+++ b/evennia/contrib/base_systems/custom_gametime/custom_gametime.py
@@ -328,4 +328,4 @@ def at_repeat(self):
             callback()
 
         seconds = real_seconds_until(**self.db.gametime)
-        self.restart(interval=seconds)
+        self.start(interval=seconds,force_restart=True)
diff --git a/evennia/utils/containers.py b/evennia/utils/containers.py
--- a/evennia/utils/containers.py
+++ b/evennia/utils/containers.py
@@ -167,7 +167,6 @@ def _load_script(self, key):
 
             # store a hash representation of the setup
             script.attributes.add("_global_script_settings", compare_hash, category="settings_hash")
-        script.start()
 
         return script
 
@@ -183,9 +182,12 @@ def start(self):
         # populate self.typeclass_storage
         self.load_data()
 
-        # start registered scripts
+        # make sure settings-defined scripts are loaded
         for key in self.loaded_data:
             self._load_script(key)
+        # start all global scripts
+        for script in self._get_scripts():
+            script.start()
 
     def load_data(self):
         """
diff --git a/evennia/utils/gametime.py b/evennia/utils/gametime.py
--- a/evennia/utils/gametime.py
+++ b/evennia/utils/gametime.py
@@ -67,7 +67,7 @@ def at_repeat(self):
             callback(*args, **kwargs)
 
         seconds = real_seconds_until(**self.db.gametime)
-        self.restart(interval=seconds)
+        self.start(interval=seconds,force_restart=True)
 
 
 # Access functions


Test patch: