Daylight effect experiment

8 views
Skip to first unread message

dvr...@gmail.com

unread,
Aug 23, 2008, 9:09:15 PM8/23/08
to endgame-singularity
Hello,

This is a patch to display a simple daylight cursor on the main map. I
find the effect interesting so I wanted to share.
http://img141.imageshack.us/my.php?image=screenshotendgamesingulks5.png

Greetings,
David

PS: the new research interface is great ;>

===================================================================
--- code/screens/map.py (revision 870)
+++ code/screens/map.py (working copy)
@@ -26,6 +26,46 @@

from location import LocationScreen

+import math
+
+class EarthImage(image.Image):
+ def __init__(self, parent):
+ super(EarthImage, self).__init__(parent, (.5,.5), (1,.667),
+ constants.MID_CENTER,
+ gg.images['earth.jpg'])
+
+
+ def redraw(self):
+ super(image.Image, self).redraw()
+ self.surface.blit(self.scaled_image, (0,0))
+
+ ### darken some part of the original map according to time
+ night_image = self.scaled_image.copy()
+ width, height = self.surface.get_size()
+ night_width = width*9/16
+ night_start = (g.pl.raw_sec % g.seconds_per_day) * (width) \
+ / g.seconds_per_day
+ night_start = night_width-1 - night_start
+
+ ## simple gradient
+ for n in range(night_width):
+ def _f(n):
+ x = float(n)/night_width
+ y = (1 - math.cos(x*math.pi)**200)
+ return int(240*y)
+ screen_x = night_start-night_width + n
+ alpha = _f(n)
+ night_image.fill((0,0,0, alpha), (screen_x, 0, 1,
height))
+ night_image.fill((0,0,0, alpha), (screen_x+width, 0, 1,
height))
+
+ ## update both sides of the zone
+ self.surface.blit(night_image,
+ (night_start-night_width,0),
+ (night_start-night_width,
0,night_width,height))
+ self.surface.blit(night_image,
+ (night_start-night_width+width,0),
+ (night_start-night_width+width,
0,night_width,height))
+
class MapScreen(dialog.Dialog):
def __init__(self, parent=None, pos=(0, 0), size=(1, 1),
anchor = constants.TOP_LEFT, *args, **kwargs):
@@ -39,8 +79,7 @@
self.background_color = gg.colors["black"]
self.add_handler(constants.TICK, self.on_tick)

- self.map = image.Image(self, (.5,.5), (1,.667),
constants.MID_CENTER,
- gg.images['earth.jpg'])
+ self.map = EarthImage(self)

self.location_buttons = {}
for location in g.locations.values():
@@ -390,6 +429,8 @@
button.text = "%s (%d)" % (location.name,
len(location.bases))
button.visible = location.available()

+ ## redraw map (daylight)
+ self.map.needs_redraw = True

def load_game(self):
save_names = g.get_save_names()

Charlie Nolan

unread,
Aug 24, 2008, 1:05:25 AM8/24/08
to endgame-s...@googlegroups.com
Hey, that's awesome. I'd actually toyed with this idea a while back,
but forgot about it, probably because of issues with the old GUI
system and the transition to the new one. Plus, I think you're the
first person (other than me) to figure out how to use the new system.
Grats!

Investigating it now.

-FM

Anne Archibald

unread,
Aug 24, 2008, 5:34:18 AM8/24/08
to endgame-s...@googlegroups.com
2008/8/23 dvr...@gmail.com <dvr...@gmail.com>:

> This is a patch to display a simple daylight cursor on the main map. I
> find the effect interesting so I wanted to share.
> http://img141.imageshack.us/my.php?image=screenshotendgamesingulks5.png

Nice idea! I have a few comments though:

* That's not what daylight looks like: in December, for example,
Antarctica mostly never sees night. The formula is available at
http://en.wikipedia.org/wiki/Day_length ; you could compute a
"darkness map" each day and roll it around for 24 hours. Might be
slow. On the other hand, it would provide a nice visual indication of
the passage of time.
* That's not what the dark side looks like: there's that beautiful
"earth at night" mosaic you could use for the dark parts. With SDL
it's probably just a question of using the image colours rather than
(0,0,0) to combine with the alpha you compute.
* It could read time.time() and start "now"; a nice touch for people who notice.
* You know people are going to want the Moon too...
* Is performance OK on flat-out mode? It might be necessary to be able
to disable it (for older systems).

Gives it a very War Room look. "These computers give us instant access
to the state of the world." All that.

Anne

dvr...@gmail.com

unread,
Aug 24, 2008, 8:33:15 AM8/24/08
to endgame-singularity
Hello,

Thanx for feedback. That code is indeed both incorrect and suboptimal.
It would take a little more time do do it properly.

I may have some spare time to work on it. Insights from the interface
writers would be appreciated ;>

What's the "earth at night" mosaic btw ? And the flat-out mode ?

I like the idea of starting the time " now() ". (I even happen to
think of an online web-based realtime version).

Greetings,
David


On 24 août, 11:34, "Anne Archibald" <peridot.face...@gmail.com> wrote:
> 2008/8/23 dvr...@gmail.com <dvr...@gmail.com>:
>
> > This is a patch to display a simple daylight cursor on the main map. I
> > find the effect interesting so I wanted to share.
> >http://img141.imageshack.us/my.php?image=screenshotendgamesingulks5.png
>
> Nice idea! I have a few comments though:
>
> * That's not what daylight looks like: in December, for example,
> Antarctica mostly never sees night. The formula is available athttp://en.wikipedia.org/wiki/Day_length; you could compute a

Charlie Nolan

unread,
Aug 24, 2008, 9:13:28 AM8/24/08
to endgame-s...@googlegroups.com
I've already fixed the performance issues. It's still a significant
hit, but it's no longer the CPU-maxer that the original patch was.
And it's only a hit on speed 3. I disabled updating it for speed 4
(it looked pretty bad anyway) and switched it so that it only updates
once every in-game minute, which makes it a non-issue on speeds 1 and
2.

I'm working on the night image (see
http://apod.nasa.gov/apod/ap001127.html ). Unfortnately, that brings
performance issues of its own. I think I spotted what I need to do,
though.

As far as the light/dark pattern not being right, I think it's best if
we ignore that for sake of simplicity. With the way the globe gets
stretched to make a rectangle, accurate lighting would look ugly. And
it'd be a nightmare to optimize the way I did for the simple lighting.

As to starting "now", that's slightly annoying. If anyone's intersted
in figuring out the offset we'd need for 00:00:00 to be midnight UTC,
I should be able to extract that from the system time and set the
initial clock appropriately.

For the moon, let's not go borrowing trouble. One celestial body at a time.

-FM

Charlie Nolan

unread,
Aug 24, 2008, 10:43:45 AM8/24/08
to endgame-s...@googlegroups.com
Et voila:
http://endgame-singularity-dev.googlegroups.com/web/singularity_night.png

Linux folks (and anyone else running from source) will need to update
to pygame 1.8.1 to get the pretty version. Everyone else will get the
new pygame version bundled in with the next .exe/.app.

I'm a little bothered by how the north pole and antarctica change
shape between day and night. That image just by chance makes it look
like they line up perfectly, but there's significantly less of both
(especially antarctica) in the night version. I could swap the
daylight image out for the one without sea ice, which makes antarctica
match better, but that one shows nothing at the north pole. *shrugs*
Probably doesn't make much difference either way.

It's pretty much ready to go into SVN now, I just need to know how
David wants to be listed in the changelog and copyright notice.
Granted, there's not much left of the code he sent in, but it was all
built off of that, so he deserves full credit. It's a whole lot
easier to improve an existing feature than to build it from scratch.

Oh, and before I forget (again), next time, attach the patch instead
of including it in the email body. I had to edit it by hand to remove
the extra linebreaks and add back in some missing spaces at the start
of lines. It's not a big deal this time, but I'd rather not repeat
the experience with a larger patch.

-FM

Anne Archibald

unread,
Aug 24, 2008, 3:25:31 PM8/24/08
to endgame-s...@googlegroups.com
2008/8/24 Charlie Nolan <funnym...@gmail.com>:

> I've already fixed the performance issues. It's still a significant
> hit, but it's no longer the CPU-maxer that the original patch was.
> And it's only a hit on speed 3. I disabled updating it for speed 4
> (it looked pretty bad anyway) and switched it so that it only updates
> once every in-game minute, which makes it a non-issue on speeds 1 and
> 2.

How about making the time between updated depend on the speed? So if
speed 3 is ten times faster than speed 2, it can update every ten
in-game minutes. This should allow speed 4 to work...

> As far as the light/dark pattern not being right, I think it's best if
> we ignore that for sake of simplicity. With the way the globe gets
> stretched to make a rectangle, accurate lighting would look ugly. And
> it'd be a nightmare to optimize the way I did for the simple lighting.

Actually it makes a very nice pattern: see
http://aa.usno.navy.mil/data/docs/earthview.php
It does make optimization a little more tricky. The formula doesn't
take much longer to compute than your soft edges already do. You could
compute a day/night shape once per day, or once per month, or
whatever, keep it in an array, and copy a shifted copy into the alpha
channel every time you update.

> As to starting "now", that's slightly annoying. If anyone's intersted
> in figuring out the offset we'd need for 00:00:00 to be midnight UTC,
> I should be able to extract that from the system time and set the
> initial clock appropriately.

I think it's nicer if 00:00:00 is the start of the game. But
time.gmtime() will tell you what the current GMT is, and you can just
keep that as a constant offset for the night drawing.

Anne

Baffo32

unread,
Aug 24, 2008, 5:12:30 PM8/24/08
to endgame-s...@googlegroups.com
On Sun, Aug 24, 2008 at 3:25 PM, Anne Archibald
<peridot...@gmail.com> wrote:
>
> Actually it makes a very nice pattern: see
> http://aa.usno.navy.mil/data/docs/earthview.php
> It does make optimization a little more tricky. The formula doesn't
> take much longer to compute than your soft edges already do. You could
> compute a day/night shape once per day, or once per month, or
> whatever, keep it in an array, and copy a shifted copy into the alpha
> channel every time you update.

I think even using a fake pattern with some curve to it would greatly
improve the realism. It should not be night on the south and north
poles at the same time.
http://time.gov/timezone.cgi?Central/d/-6/java shows a nice
approximation.

I'm having a bit of difficulty trying to extract a formula for the
earth region in darkness, or the brightness of a given
latitude/longitude pair, from the information at
http://en.wikipedia.org/wiki/Day_length .

Charlie Nolan

unread,
Aug 24, 2008, 6:46:21 PM8/24/08
to endgame-s...@googlegroups.com
The problem with speed 4 is that a day passes in 1/5th of a second,
which is enough time for the GUI to update 6 times at 30FPS. No
matter what I do, it's going to look very jerky.

I'll probably add options for the day/night cycle and FPS before
releasing 0.29. If I scale my desktop back to 400 MHz (~XO-1 speed),
it runs fairly nicely when set at 10FPS, and slows noticably but not
catastrophically on speed 3.

If someone wants to write up a more accurate day/night pattern, go
ahead, but be warned that *you're* going to have to do the
optimization on it. I want no part of that mess, and it won't go in
until it runs fast enough.

-FM

Anne Archibald

unread,
Aug 24, 2008, 6:50:34 PM8/24/08
to endgame-s...@googlegroups.com
2008/8/24 Baffo32 <baf...@gmail.com>:

Here's a patch.

* It displays the correct day/night regions as a function of time and
season. (Though there are some approximations.)
* It starts now, as reported by time.gmtime()
* The day/night shape is changed once a day.
* On the "slow" modes the day/night region walks around the earth; on
the fastest mode it displays only at midnight. This way you can see
time passing from the shape of the day/night region.
* Every update, unfortunately, requires a blit of the whole screen;
nonetheless it's plenty fast on my several-years-old laptop. We should
still have a mode to turn it off.
* I've never written pygame code before so there are some weirdnesses
with clipping regions I never figured out.
* I added Montreal to the list of North American cities (though only
in English as I don't know what it's called in any of the other
languages).
* Some of the class variables in the map should maybe be elsewhere.

Anne

patch
singularity.png

Charlie Nolan

unread,
Aug 24, 2008, 7:10:06 PM8/24/08
to endgame-s...@googlegroups.com
Wow, I really wasn't expecting to see anything this fast. Nicely done!

The performance is actually not nearly as bad as I was expecting. It
didn't even really change.

Can you blur the edges slightly, like we were doing with the square
version? Even a degree or so of transition would really help with
those jagged edges.

Oh, and I'll need to know how you want to be listed in the changelog/copyright.

-FM

Anne Archibald

unread,
Aug 24, 2008, 8:11:44 PM8/24/08
to endgame-s...@googlegroups.com
2008/8/24 Charlie Nolan <funnym...@gmail.com>:

> The performance is actually not nearly as bad as I was expecting. It
> didn't even really change.
>
> Can you blur the edges slightly, like we were doing with the square
> version? Even a degree or so of transition would really help with
> those jagged edges.

I tried blurring a bit, but since pygame doesn't provide either
accelerated blur or gradient operations (without using surfarray and
numpy) I would have to do it pixel-by-pixel. I've attached a patch to
do that; fiddle the variable "gradient width" to adjust it, but on my
machine, by 10 or 20 pixels the slowdown was visible. As an
alternative, the patch includes simple antialiasing - essentially a
single-pixel blur - which totally removes the visible jaggies (but
fails to reproduce the real blurriness of the terminator) with minimal
slowdown.

> Oh, and I'll need to know how you want to be listed in the changelog/copyright.

"Anne M. Archibald" is good. If you're listing everyone's email
address, feel free to use this one.


Anne

patch-2

Charlie Nolan

unread,
Aug 24, 2008, 8:28:33 PM8/24/08
to endgame-s...@googlegroups.com
I was actually thinking you'd do it as part of the main computation
(so that the gradient would be perpendicular to the shadow edge), but
this looks fine. We can figure out how to make it fancier later on,
if we want.

It's in SVN, r877.

-FM

On 8/24/08, Anne Archibald <peridot...@gmail.com> wrote:

dvr...@gmail.com

unread,
Aug 26, 2008, 3:29:43 PM8/26/08
to endgame-singularity
Hello everyone,

Thanx for the work, I wasn't expecting anything to come out of the
tiny patch so soon ! It's beautiful with the night map and the correct
math !
I think we could use some precalculation, because it's even prettier
IMHO with a gradient of a few hundreds of pixels width - but
expansive. Wouldn't 365 precomputed masks aproximately do the job, or
even 188 ?

I've been working on the finance screen lately. I've got a working
prototype, but i'm cheating a bit to get the figures to match (I don't
yet well understand the whole process). Shall I sent you a copy, FM ?
As you said, it may be quite easy for you to work something out from
existing code. I think this could be cleaner if we could somehow
centralize all costs calculation (actual calculation for a fraction of
time and projection for the rest of the day). Any idea ?

Cheers,
David

On 25 août, 02:28, "Charlie Nolan" <funnyman3...@gmail.com> wrote:
> I was actually thinking you'd do it as part of the main computation
> (so that the gradient would be perpendicular to the shadow edge), but
> this looks fine. We can figure out how to make it fancier later on,
> if we want.
>
> It's in SVN, r877.
>
> -FM
>
> On 8/24/08, Anne Archibald <peridot.face...@gmail.com> wrote:
>
> > 2008/8/24 Charlie Nolan <funnyman3...@gmail.com>:

Anne Archibald

unread,
Aug 26, 2008, 4:31:10 PM8/26/08
to endgame-s...@googlegroups.com
2008/8/26 dvr...@gmail.com <dvr...@gmail.com>:

>
> Hello everyone,
>
> Thanx for the work, I wasn't expecting anything to come out of the
> tiny patch so soon ! It's beautiful with the night map and the correct
> math !
> I think we could use some precalculation, because it's even prettier
> IMHO with a gradient of a few hundreds of pixels width - but
> expansive. Wouldn't 365 precomputed masks aproximately do the job, or
> even 188 ?

Since the masks are typically 800x600x4 bytes, I don't think 365 of
them is a good idea - and at least in fast mode you can already see
sizable steps as it advances by a day. You could store the information
needed to generate the mask, but the slow step is all those
single-pixel value settings. If you were willing to make the game
depend on numpy, you could use numpy to do the calculation directly
and as exactly as you felt inclined.

One possibility worth looking into is producing the mask by averaging,
say, five days' worth of masks. This won't give you a nice smooth
gradient, though, and five full-screen blits won't be cheap.

The real terminator is quite wide:
http://solarsystem.nasa.gov/multimedia/display.cfm?IM_ID=1879
But since smoothly interpolating between our daytime and nighttime
images is pretty artificial, and they don't line up, I don't know that
it's worth the trouble of trying for more realism. I think the current
setup has the look of one of those day/night clocks:
http://www.gadgetchamp.com/2007/07/27/geochron-world-clock-all-the-time-in-the-world/

I played a quick game (on Very Easy) and it's borderline distracting.
One thing it would be nice to change is that when you start fast
mode, the image jumps to midnight GMT; when it stops, the image jumps
to whatever time fast mode stops at. There's no getting around the
second one, but it would be nicer if the image just stayed at the time
of day it was at when you hit "fast".

Anne

evilm...@emhsoft.com

unread,
Aug 26, 2008, 4:41:26 PM8/26/08
to endgame-s...@googlegroups.com

Whe this got talked about last time, weren't we were looking at having
speed 4 just have a "perpetual twilight" look?

Charlie Nolan

unread,
Aug 26, 2008, 4:43:35 PM8/26/08
to endgame-s...@googlegroups.com
We already depend on numpy, so if you want to calculate things with
it, go ahead. In fact, there's a tweak in to make pygame's pixel
arrays use numpy instead of Numeric when both are installed.

You could lower the cost of the averaging by just averaging the
previous mask with the current one. To change the thickness, you just
weight it towards the old or new image. I don't think it's likely to
give a very good result, but I could be wrong.

Actually, that terminator isn't all that wide. I read it as maybe 8
pixels, with a radius of 80. That gives a width of 5.7 degrees, or
roughly 13 horizontal pixels (10 vertical) at 800x600.

Charlie Nolan

unread,
Aug 26, 2008, 4:44:31 PM8/26/08
to endgame-s...@googlegroups.com
emh: I tried doing a flat blend of the two at speed 4, but the switch
was way too jarring, and it didn't look very good.

Charlie Nolan

unread,
Aug 26, 2008, 4:46:48 PM8/26/08
to endgame-s...@googlegroups.com
Oh, and feel free to send that in, David. Even though I wrote the
framework we're using, I still hate building a GUI. The prediction
will be much more interesting to work on.

-FM

Anne Archibald

unread,
Aug 26, 2008, 6:20:42 PM8/26/08
to endgame-s...@googlegroups.com
2008/8/26 <evilm...@emhsoft.com>:

> Whe this got talked about last time, weren't we were looking at having
> speed 4 just have a "perpetual twilight" look?

I find the current setup - show the same time every day - rather nice:
you have a visual indication of time passing because the terminator
changes shape.

Anne

Charlie Nolan

unread,
Aug 26, 2008, 6:34:09 PM8/26/08
to endgame-s...@googlegroups.com
I tend to agree. It looks quite nice.

-FM

On 8/26/08, Anne Archibald <peridot...@gmail.com> wrote:
>

Anne Archibald

unread,
Aug 26, 2008, 8:52:52 PM8/26/08
to endgame-s...@googlegroups.com
2008/8/26 Charlie Nolan <funnym...@gmail.com>:

> We already depend on numpy, so if you want to calculate things with
> it, go ahead. In fact, there's a tweak in to make pygame's pixel
> arrays use numpy instead of Numeric when both are installed.

Oh! Really? I hadn't realized. Then here's a quick patch.

I compute the (sine of the) Sun's altitude above the horizon, in solar
diameters. The gradient should be from -0.5 to 0.5. Instead of just
clipping values to that range (using a linear gradient) or using some
"correct" gradient based on how much of the Sun is above the horizon,
I used a hyperbolic tangent to compress the range (it has slope 1 at
the origin but maps the real line to (-1,1)). So the gradient has
slightly elongated tails. Anyway, it works, and produces a gradient
that's mostly narrow except near the poles near equinox. And it runs
reasonably quickly (no python looping); optimizations could definitely
be done.

I also don't know whether it's safe to assume any of numpy, numarray,
or Numeric is installed, or even which one, so I have a gruesome
suspender-and-belt import. That could be cleaned up, as could the
alternative implementations, if people are happy with this one and
know more about what we can assume is installed.

Anne

patch-3

Charlie Nolan

unread,
Aug 26, 2008, 9:36:18 PM8/26/08
to endgame-s...@googlegroups.com
In the future, just assume NumPy. It's listed in the README and
directly imported elsewhere, so your code won't be the only thing
breaking if it's missing.

-FM

On 8/26/08, Anne Archibald <peridot...@gmail.com> wrote:

Charlie Nolan

unread,
Aug 26, 2008, 9:47:16 PM8/26/08
to endgame-s...@googlegroups.com
Oh, and the only reason I'm being timid with requiring pygame 1.8 is
that it's still new enough to not be widely distributed by the various
Linux package managers. NumPy doesn't have that problem.

-FM

On 8/26/08, Charlie Nolan <funnym...@gmail.com> wrote:

Charlie Nolan

unread,
Aug 26, 2008, 10:04:57 PM8/26/08
to endgame-s...@googlegroups.com
The patch looks great to me. I stripped out the "maybe not numpy"
code, but that's all. r878

The strange effect at the poles around equinox looks believable to me,
so I wouldn't worry about it. Then again, if you want to try
something even more complex, you're certainly welcome to. Everything
else you've sent in has impressed me, so I'd be happy to take a look.

So, is it just geometry you excel at, or should I sic you on some of
the other hard problems I have in mind? :)

Anne Archibald

unread,
Aug 26, 2008, 11:37:06 PM8/26/08
to endgame-s...@googlegroups.com
2008/8/26 Anne Archibald <peridot...@gmail.com>:

> I played a quick game (on Very Easy) and it's borderline distracting.
> One thing it would be nice to change is that when you start fast
> mode, the image jumps to midnight GMT; when it stops, the image jumps
> to whatever time fast mode stops at. There's no getting around the
> second one, but it would be nicer if the image just stayed at the time
> of day it was at when you hit "fast".

Attached is a patch to do this.

Once again I'm not sure the coding style is all it could be, but it
does appear to work, and provide no more jumps than necessary.

Anne

nojump-patch

Charlie Nolan

unread,
Aug 27, 2008, 3:51:32 AM8/27/08
to endgame-s...@googlegroups.com
Doesn't look any worse than some of the stuff I've put in.
Complicated logic takes complicated code, there's not a lot to be done
about it. Some high-level explanation of what you're doing and why
wouldn't be amiss, but I'll confess to being pretty bad about that
myself.

I do have one question, though. What's the point of this "if False:"
block that's been hanging around for a bit? Is it just dead code, or
is it intended to be something we can enable?

Applied the patch. Things were behaving badly on user pause, so I
added a line to force an update when the user changes the speed. r879

-FM

On 8/26/08, Anne Archibald <peridot...@gmail.com> wrote:

Anne Archibald

unread,
Aug 27, 2008, 1:36:15 PM8/27/08
to endgame-s...@googlegroups.com
2008/8/27 Charlie Nolan <funnym...@gmail.com>:

> Doesn't look any worse than some of the stuff I've put in.
> Complicated logic takes complicated code, there's not a lot to be done
> about it. Some high-level explanation of what you're doing and why
> wouldn't be amiss, but I'll confess to being pretty bad about that
> myself.
>
> I do have one question, though. What's the point of this "if False:"
> block that's been hanging around for a bit? Is it just dead code, or
> is it intended to be something we can enable?

The "if False:" was to enable the first attempt at blurring. There's
no real point having it there any more, as it's less accurate and
slower than the numpy-based solution. I'm afraid the antialiased
version needs to stay, though, since it's used when can_twiddle_alpha
is False.

Anne

Charlie Nolan

unread,
Aug 28, 2008, 4:56:10 AM8/28/08
to endgame-s...@googlegroups.com
One of the regulars in IRC prodded me about the day/night mismatch, so
I spent a couple hours tracking down the "correct" night image,
deciding it didn't look good enough, and finally fiddling around in
GIMP until I had a composite image that works well.

-FM

Reply all
Reply to author
Forward
0 new messages