Game Loop?

DrEvil wrote:

: There is the Linux Game Development Center mailing list and newsgroup,
: which is nice… It’s not too noisy, it prefers to go silent rather
: than getting noisy, but it doesn’t mean that it is always low-traffic.
: Bring up a question and it’ll get discussed.

Linux Game Development Center ML and newsgroup? Where can I find more
information on this??? :slight_smile: Tell me please :slight_smile:

The web site is at http://sunsite.auc.dk/lgdc/, the mailing list I don’t
know since I only use the newsgroup gateway at
news://sunsite.auc.dk/sunsite.linux.linuxgames … But the information
should be on their pages.–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

DrEvil wrote:

: There is the Linux Game Development Center mailing list and newsgroup,
: which is nice… It’s not too noisy, it prefers to go silent rather
: than getting noisy, but it doesn’t mean that it is always low-traffic.
: Bring up a question and it’ll get discussed.

Linux Game Development Center ML and newsgroup? Where can I find more
information on this??? :slight_smile: Tell me please :slight_smile:

The web site is at http://sunsite.auc.dk/lgdc/, the mailing list I don’t
know since I only use the newsgroup gateway at
news://sunsite.auc.dk/sunsite.linux.linuxgames … But the information
should be on their pages.

That site (IMHO) appears to be pretty damn close to dead. I want high traffic,
damnit!

I still like the idea of a linuxgamedev mailing list. Advertise it, get people
to sign up, we have cool forum for game development discussion, eh?


Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

Nichola

vining at pacificcoast.net wrote:

The web site is at http://sunsite.auc.dk/lgdc/, the mailing list I don’t
know since I only use the newsgroup gateway at
news://sunsite.auc.dk/sunsite.linux.linuxgames … But the information
should be on their pages.

That site (IMHO) appears to be pretty damn close to dead. I want high
traffic, damnit!

It’s not “high traffic” like slashdot.org is, but it is not dead, you
have an update every week or two. If you submit something, it will most
probably get on the site.

I still like the idea of a linuxgamedev mailing list. Advertise it, get
people to sign up, we have cool forum for game development discussion, eh?

You could just tell interested people to come on the LGDC list. True,
maybe it isn’t advertised enough, but there is discussion there and
while it is low-traffic most of the time, when somebody brings up an
issue, it goes high-traffic until that issue is resolved, so I do not
consider it “dead” as such…–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

Pierre Phaneuf wrote:

vining at pacificcoast.net wrote:

The web site is at http://sunsite.auc.dk/lgdc/, the mailing list I don’t
know since I only use the newsgroup gateway at
news://sunsite.auc.dk/sunsite.linux.linuxgames … But the information
should be on their pages.

That site (IMHO) appears to be pretty damn close to dead. I want high
traffic, damnit!

It’s not “high traffic” like slashdot.org is, but it is not dead, you
have an update every week or two. If you submit something, it will most
probably get on the site.

I still like the idea of a linuxgamedev mailing list. Advertise it, get
people to sign up, we have cool forum for game development discussion, eh?

You could just tell interested people to come on the LGDC list. True,
maybe it isn’t advertised enough, but there is discussion there and
while it is low-traffic most of the time, when somebody brings up an
issue, it goes high-traffic until that issue is resolved, so I do not
consider it “dead” as such…

Well, let’s use that list for game development discussion, until we find
it too noisy or otherwise unsatisfactory.

PS: I’m still trying to scrape together enough time to post my game loop
question, it’s been a busy few days. :-(–
Marc A. Lepage
Software Developer
Molecular Mining Corporation
http://www.molecularmining.com/

Marc A. Lepage wrote:

Pierre Phaneuf wrote:

vining at pacificcoast.net wrote:

The web site is at http://sunsite.auc.dk/lgdc/, the mailing list I don’t
know since I only use the newsgroup gateway at
news://sunsite.auc.dk/sunsite.linux.linuxgames … But the information
should be on their pages.

That site (IMHO) appears to be pretty damn close to dead. I want high
traffic, damnit!

It’s not “high traffic” like slashdot.org is, but it is not dead, you
have an update every week or two. If you submit something, it will most
probably get on the site.

I still like the idea of a linuxgamedev mailing list. Advertise it, get
people to sign up, we have cool forum for game development discussion, eh?

You could just tell interested people to come on the LGDC list. True,
maybe it isn’t advertised enough, but there is discussion there and
while it is low-traffic most of the time, when somebody brings up an
issue, it goes high-traffic until that issue is resolved, so I do not
consider it “dead” as such…

Well, let’s use that list for game development discussion, until we find
it too noisy or otherwise unsatisfactory.

That list seems to get a lot of newbie questions. It would be nice for game
developers only.

Topica lists are easy, as mentioned before, and sourceforge also has lists, along
with cvs and web hosting, I’m a member of both and could easily set them up.

PS: I’m still trying to scrape together enough time to post my game loop
question, it’s been a busy few days. :frowning:

I’m very interested in this. I have been looking for a game library for a while
now. The current libs (SDL, Clanlib, plib) seem to deal with graphics and sound,
and some other utilities, but aren’t what I’d consider “game” libraries. They
don’t help with things like collision detection, Finite state machines, resource
handling (well clanlib does), sprites (not just drawing, but sprite lists, and
animation lists, and motion handling, so you can just call a function to move a
sprite from A to B running animation C and a set speed).

This is the sort of helper library I need for my pet project, a game
constructor. I have a GUI toolkit, and either SDL or clanlib for the low level
game stuff, but I would like a helper lib to do the above and more. The game loop
stuff mentioned would fit into this.

Bye - Joel.

: I’m very interested in this. I have been looking for a game library
for a while
: now. The current libs (SDL, Clanlib, plib) seem to deal with graphics
and sound,
: and some other utilities, but aren’t what I’d consider "game"
libraries. They
: don’t help with things like collision detection, Finite state
machines, resource
: handling (well clanlib does), sprites (not just drawing, but sprite
lists, and
: animation lists, and motion handling, so you can just call a function
to move a
: sprite from A to B running animation C and a set speed).
:
: This is the sort of helper library I need for my pet project, a game
: constructor. I have a GUI toolkit, and either SDL or clanlib for the
low level
: game stuff, but I would like a helper lib to do the above and more.
The game loop
: stuff mentioned would fit into this.
:
: Bye - Joel.

I am in no way denying that SDL is a great library. However, as far as a
’game’ library goes, Allegro is a great choice. There are collision
routines, a full gui system, a package file system, and while it is not
as well developed in it’s linux support as SDL, it is well developed for
dos, and I look for it’s Linux support to only improve :slight_smile: You can find
out more about it at:

http://www.talula.demon.co.uk/

P.S: Only the Work in progress version has Linux support :slight_smile:

DrEvil wrote:

: I’m very interested in this. I have been looking for a game library
for a while
: now. The current libs (SDL, Clanlib, plib) seem to deal with graphics
and sound,
: and some other utilities, but aren’t what I’d consider “game”
libraries. They
: don’t help with things like collision detection, Finite state
machines, resource
: handling (well clanlib does), sprites (not just drawing, but sprite
lists, and
: animation lists, and motion handling, so you can just call a function
to move a
: sprite from A to B running animation C and a set speed).
:
: This is the sort of helper library I need for my pet project, a game
: constructor. I have a GUI toolkit, and either SDL or clanlib for the
low level
: game stuff, but I would like a helper lib to do the above and more.
The game loop
: stuff mentioned would fit into this.
:
: Bye - Joel.

I am in no way denying that SDL is a great library. However, as far as a
‘game’ library goes, Allegro is a great choice. There are collision
routines, a full gui system, a package file system, and while it is not
as well developed in it’s linux support as SDL, it is well developed for
dos, and I look for it’s Linux support to only improve :slight_smile: You can find
out more about it at:

http://www.talula.demon.co.uk/

P.S: Only the Work in progress version has Linux support :slight_smile:

I used to use allegro on dos when I programmed in DJGPP a few years ago. I
didn’t know it included collision detection, so thanks. I’ll have another
look at it.

Bye - Joel.

: I used to use allegro on dos when I programmed in DJGPP a few years
ago. I
: didn’t know it included collision detection, so thanks. I’ll have
another
: look at it.
:
: Bye - Joel.

I think basic collision detection is built in, I know that if you want
’Pixel Perfect’ collision detection there’s a package for Allegro called
PPCol or something like that. Anyway, good luck :slight_smile:

DrEvil
@EvilTypeGuy

“Marc A. Lepage” wrote:

PS: I’m still trying to scrape together enough time to post my game loop
question, it’s been a busy few days. :frowning:

My thoughts are below. I reproduce them here, but I’ve also posted to
comp.games.development.programming.algorithms and (on sunsite.auc.dk)
sunsite.linux.linuxgames. I intend the discussion to take place there,
and not to hijack the SDL list. If those sites lack the capacity to
discuss issues of this nature, I’ll probably consider starting a private
games development discussion list of some sort.

I’m interested in the game update loop as applied to networked RTS
games. I would like to start some serious discussion on this issue. To
begin, I have reference material from a few sources.

First, Andrew Rollings and Dave Morris write about game loops in their
book Game Architecture and Design:

----- BEGIN QUOTE -----
These game developers attempted to use the frame rate as a timer. They
would choose a frame rate (possibly dictated by the hardware) – say,
thirty frames per second (fps) – and construct all their game logic
around that. There would be one AI tick every frame, so, doing the math,
you can see that each game object would be updated to move the distance
it could normally move in each thirtieth of a second. Note that this
technique is still used with platforms that are limited in power and
universally identical, such as the Game Boy. This technique has the
least overhead. No special effort is required to dynamically adjust the
timing parameters.

This was all fine and good, but there were two main problems. The first
was that owners of faster machines weren’t too pleased that their
brand-new game didn’t take advantage of their machine’s speed, and that
the game looked exactly the same on their friend’s machine that had a
processor half as fast.

The second (and rather more serious) problem was that, below a certain
threshold level of processing power, the game would suddenly halve in
speed. If the AI tick took just longer than one frame to calculate, then
every other frame would be skipped, resulting in a drop in speed. The
same sort of thing could happen if a frame took too long to draw. All in
all, a bit of a disaster.

Fortunately, some thinking was done on the subject, and a couple of
suitable solutions were developed. I’ll call them semi-decoupling and
full decoupling.

Semi-decoupling is the simpler of the two solutions. The trick is to
decouple the frame rate update from the AI ticks. This technique is
suitable for games that don’t particularly stretch the hardware of the
average midrange machine, but also want to run acceptably well on the
lower-end machines.

The AI runs at a fixed rate as before, but the frame rate just runs as
fast as it possibly can. Assume the AI is running at 30 ticks per second
as before. A separate loop draws each frame, and then waits for the next
AI tick to be complete before drawing the next one. This means that, if
the frame takes too long to draw, it would not be such a disaster as
before. The AI loop would continue independently, because it wouldn’t be
stalled waiting for the frame to complete, and the next frame to be
drawn would be correct. The player may notice a drop in frame rate, and
some of the animation may be slightly jerkier, but the important thing
is that the internal AI would still be running correctly. The main
disadvantage of this technique is that your maximum frame rate is
limited to the fixed tick rate of the AI loop. There is no point in
updating the screen if nothing has changed in the AI, so the drawing
loop will be idle while this is going on. This technique is fine, if you
are sure that your AI is going to be run at a constant rate and you
don’t mind being limited to that rate. But what if you want your frame
rate to be the maximum possible, irrespective of the speed of the AI
loop? This is where full decoupling comes in. Most games today use this
technique.

Full decoupling attempts to run the AI loop as fast as possible. A
reference timer is used to adjust the changes in game object states per
AI tick, so that the game does not appear to speed up and slow down.
This means that, on faster machines, there will be more AI ticks per
second, so, for each tick, the delta value (which is the reciprocal of
the length of the tick) will be smaller. On slower machines, ticks will
take longer, and so the delta value will be larger. Imagine that we are
animating a clockface that has one hand. This hand rorates once every
second. Internally, the AI tick updates this clock according to the
delta value. The clock is drawn at the end of each AI tick. Obviously,
the smoothness of the animation depends on the frequencyof the AI ticks.
The animation will still show the hand performing a full rotation every
second, but the smoothness of the animation will vary.

This is a pretty smart technique that allows a program to max out frame
rates, but it is not true full decoupling. The frame rate is still
limited by the rate of AI ticks. It is impossible to have more than
that. To achieve full decoupling would be difficult, but possible. To do
this, the AI loop and the frame-update loop run completely separately,
most likely in separate threads. Then the frame loop is given the
ability to take a “snapshot” of the state of the AI loop whenever it
likes (assuming that it is not so often that it chokes the AI loop), as
long as at least one visible object has been processed. Care has to be
taken to make sure than an object is not halfway through being processed
when the snapshot is taken (it may be in an internally inconsistent
state), and the easiest way to achieve this is to set the snapshot
granularity to the object level.
----- END QUOTE -----

Second, Dave Pottinger of Ensemble Studios discusses different lengths
for the main game update loop in his article Coordinated Unit Movement:

So, assume I wish to run a distributed (peer-to-peer) discrete event
simulation. That is, I want the exact same thing to happen on each node.
Forget animation, and consider just the simulation itself.

The simplest method, the one I’ve been planning on until now, is to use
a fixed frame rate. For example, suppose I choose 20fps. Then every node
runs the simulation at 20 ticks per second, and attempt to draw a frame
of animation for each tick. If the computer is faster, then it waits. If
it is slower, it drops frames of animation. If it is too slow, then the
entire distributed simulation runs at the speed of the slowest node, or
that node is dropped.

In this case, the fixed frame rate is critical to the synchronizing of
the distributed simulation. Every node must perform the same
calculations.

Suppose a unit is at location (100,100). It wishes to move to (200,200).
Its movement speed is 4 per tick. Pythagoras tells us the distance is
approximately 141.42. Rounding up, it will take us 36 ticks to make the
journey. That is, 1.8 seconds. Each node can use floating point
calculations to handle the movement, and round the unit’s location to
the nearest map point each tick. That puts the simulation always in
discrete integer locations, for any collision/pathing calculations
during that journey.

The key point is: those 36 integer locations along the way must be
identical on every node. It’s okay for the floating calculations to be
slightly different (say, different precision), as long as they do not
cause the intermediate integer locations to diverge, even once.

So, a fixed frame rate is simple to handle, computationally, in the
distributed simulation. How can I use a less coupled game loop and still
maintain the integrity of the simulation?

Let’s suppose first, that one node runs at 20 ticks per second, but the
other is more powerful and can run at 30 ticks per second. Can this be
done?

Both must make that same journey in 1.8s. The first node can do that in
36 ticks, but the second node is trickier. In that time, it will
simulate 54 ticks. Because of that, the unit will move 2.67 each tick.

If a collision happens during that journey, it may occur at different
time and space coordinates on the different nodes! Trivially, because of
the finer granularity of the second node, it may collide earlier.

Clearly, I cannot allow the simulation to run differently on each node.
One solution, would be to have the faster node run two simulations, in
effect. It would run a 20 ticks per second simulation of the journey for
simulation purposes, and a 30 ticks per second simulation of the journey
for display purposes. But this seems wasteful. It allows the second node
to potential display something that is not in fact happening (such as
melting into an object it should collide with, for a frame or two). And
it means deciding how slow to run the simulation.

That last point is key, I think. For a distributed simulation, I don’t
see any way of getting around the fact that each node must run the same
simulation, at the same rate. Let’s try this.

Let’s say that each node can simulate as fast as it wants, but that
pathfinding, collision detection, etc. will only occur at a fixed rate
of 10 ticks per second. Further, let’s require each node to have a tick
at that exact time. So, we are saying that each node can simulate at its
preferred granularity, but all the logic will occur at fixed ticks: 10
per second.

In this case, the slow node simulates an extra tick between every
“logic” tick. The fast node simulates two extra ticks between every
“logic” tick.

If the moving unit is going to have a collision 0.5s into its journey,
it will on each node. This will occur at tick 10 on the first node, and
tick 15 on the second. That’s “logic” tick 5 for both.

Now, it may be that on the first node, the objects overlap on tick 9.
And on the second node, they may overlap on tick 13. But since those
aren’t “logic” ticks, the collision doesn’t occur. The simulations may
diverge in state, but not in logic. 10 times per second, they are
effectively synchronized.

The above assumes each node runs a fixed simulation rate, but it could
easily be extended to variable rate, so long as the above constraints
are met. I worry about the precision of floating point numbers. How can
I be sure that simulation state is correct on each node, at each “logic”
tick?

I suppose I could always plot the unit’s positions at those critical
ticks ahead of time, and even if it diverged on one node, “snap” the
unit’s position to that location when appropriate.

Anyways, I hope this made sense. I’d really like to hear serious
comments on all this discussion, as I’m hoping to decide how much of a
hassle all of this will be to implement, or if there are critical flaws
in my thinking.–
Marc A. Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.

My thoughts are below. I reproduce them here, but I’ve also posted to
comp.games.development.programming.algorithms and (on sunsite.auc.dk)
sunsite.linux.linuxgames. I intend the discussion to take place there,
and not to hijack the SDL list. If those sites lack the capacity to
discuss issues of this nature, I’ll probably consider starting a private
games development discussion list of some sort.

Full decoupling isn’t really all that hard. What passes for “AI” in
my game (character positions/etc) is totally independant of the frame rate…
because it’s on a server, which is doing all the update work. So,all you need
to do is to spawn yourself two threads. One processes the client/server
communications and updates the world state. Have this one limited by the # of
ticks. The second thread renders the local world state based on pre-determined
information. Since the frame rate is CPU intensive, especially on a Voodoo
(where, if you miss the # of calls to glSwapBuffers needed to make up your
screen refresh rate, it halves), so if you can’t access data for a certain
component of your game state (mutex is locked), skip it and go back to it
later. I do it by making multiple passes through my object list - if an object
is accessible, draw it; if not, don’t draw it and don’t toggle its “drawn”
flag. Then you make passes through until you’re all alright. Kind of like a
bubble sort. I expect that this could be optimized, but I don’t think
converting it to use a different sort of data structure would really be worth
it.

Nicholas

vining at pacificcoast.net wrote:

Full decoupling isn’t really all that hard. What passes for “AI” in
my game (character positions/etc) is totally independant of the frame rate…
because it’s on a server, which is doing all the update work. So,all you need
to do is to spawn yourself two threads. One processes the client/server
communications and updates the world state. Have this one limited by the # of
ticks. The second thread renders the local world state based on pre-determined
information.

That’s client/server. Quake is like that. Mine is peer-to-peer.

Another analogy I though of, is that I am requiring what in animation is
know as “key frames.” I am requiring that no matter what, the key frames
of each peer are identical. The difference (wrt client/server) is that
mine are all locally calculated.–
Marc A. Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.

Something I don’t understand. (And forgive me for what may be
a silly question.)

You want -one- simulation, right? But multiple -presentations-.
So why go to all the trouble to have both (or all 10) nodes
run the same simulation?

Seems to me that the “Right Way” to approach this would be to
build an architecture that allows you to leverage the collective
CPU power of all the nodes to run the One True Simulation in
a distributed manner, and ensure that they also can easily get
at all the data they need to produce the presentation whenever
necessary (20 times per second or whatever).

So if you’re simulating a 2D world, chop it up into variable-sized
rectangles and farm out the bigger ones to the faster/freer machines,
smaller ones to slower/more-loaded machines. Each machine does
its bit of the simulation, and they all talk to each other when
necessary to obtain the necessary data to draw the presentation.
If you do the scheduling right, you can gaurantee that the simulation
occurs at the proper rate.

I’m not saying this is by any means trivial, and I see that
the distribution of presentation data is likely to be the bottleneck,
but bandwidth is getting cheaper and cheaper. And actually,
if we think about it a bit, this might not be such a problem -
each node is probably only looking at a subset of the whole
world, so the amount of presentation data that needs to move
around may be a lot less than all the data in the simulation. And
all the machines have to talk to each other once per sim tick,
so they can ship the latest presentation data around with
the sync data. Use IP multicast, might be pretty fast.

OK, so I’m a dreamer…

– Joe Knapka

“Marc A. Lepage” wrote:>

vining at pacificcoast.net wrote:

Full decoupling isn’t really all that hard. What passes for “AI” in
my game (character positions/etc) is totally independant of the frame rate…
because it’s on a server, which is doing all the update work. So,all you need
to do is to spawn yourself two threads. One processes the client/server
communications and updates the world state. Have this one limited by the # of
ticks. The second thread renders the local world state based on pre-determined
information.

That’s client/server. Quake is like that. Mine is peer-to-peer.

Another analogy I though of, is that I am requiring what in animation is
know as “key frames.” I am requiring that no matter what, the key frames
of each peer are identical. The difference (wrt client/server) is that
mine are all locally calculated.


Marc A. Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.

I know this is rapidly drifting offtopic, but…

So if you’re simulating a 2D world, chop it up into variable-sized
rectangles and farm out the bigger ones to the faster/freer machines,
smaller ones to slower/more-loaded machines. Each machine does
its bit of the simulation, and they all talk to each other when
necessary to obtain the necessary data to draw the presentation.

This design requires alot more work than client/server, but there are
several things they have in common…

  • The status of all players (location, velocity) needs to be sent often
    enough to keep the graphics smooth.
  • Certain state changes (collision detection, capturing a resource) need
    to be negotiated with a “simulation authority” so that the world is
    well-defined at every moment (either player 1 gets the medkit or player
    2 does).

The simulation authority can be 1 host who decides everything (typically
the server), or it can be divided among several hosts (each in charge of
a little bit of the world).

If you do the scheduling right, you can gaurantee that the simulation
occurs at the proper rate.

Ideally, but not necessarily. State changes especially require that the
authority recvs, applies the appropriate logic, and confirms or denies
the desired action. Drop a packet, and the player’s simulation might
stall while it retries the packet. Sometimes there is nothing you can do
about high latency or lossy links

Anyway, I go into such topics in depth at my website:

http://www.CodeWhore.com/

A good place for followups would be comp.games.design.*

Matt

/* Matt Slot, Bitwise Operator * One box, two box, yellow box, blue box. *

Joe Knapka wrote:

Something I don’t understand. (And forgive me for what may be
a silly question.)

You want -one- simulation, right? But multiple -presentations-.
So why go to all the trouble to have both (or all 10) nodes
run the same simulation?

Seems to me that the “Right Way” to approach this would be to
build an architecture that allows you to leverage the collective
CPU power of all the nodes to run the One True Simulation in
a distributed manner, and ensure that they also can easily get
at all the data they need to produce the presentation whenever
necessary (20 times per second or whatever).

So if you’re simulating a 2D world, chop it up into variable-sized
rectangles and farm out the bigger ones to the faster/freer machines,
smaller ones to slower/more-loaded machines. Each machine does
its bit of the simulation, and they all talk to each other when
necessary to obtain the necessary data to draw the presentation.
If you do the scheduling right, you can gaurantee that the simulation
occurs at the proper rate.

I’m not saying this is by any means trivial, and I see that
the distribution of presentation data is likely to be the bottleneck,
but bandwidth is getting cheaper and cheaper. And actually,
if we think about it a bit, this might not be such a problem -
each node is probably only looking at a subset of the whole
world, so the amount of presentation data that needs to move
around may be a lot less than all the data in the simulation. And
all the machines have to talk to each other once per sim tick,
so they can ship the latest presentation data around with
the sync data. Use IP multicast, might be pretty fast.

OK, so I’m a dreamer…

It’s an idea.

RTS games are typically neither client/server nor blackboard
architecture. They are peer to peer.

If you display a mini map and that player has units all over the map,
that is a lot of information to send to that node from all the others.
Further, every unit that crosses a boundary must suddenly be simulated
on another node.

Finally, there is the question of latency. With local simulation of the
entire world, I can tell a unit to do something. It is scheduled for a
few ticks later. My node already knows about it, it need only tell the
other nodes.

If that order involves something not simulated on my node, then my node
needs to inform the authority node, which then sends the order to all
nodes. That’s twice the latency. My node can’t just continue, because
without authority, it can’t assume the order is valid. The cost of
rolling back is too much to proceed optimistically.

So, in my architecture, each peer node computes exactly the same
simulation. When an order is created, the peer node knows whether it is
valid or not. If valid, it is sent to the other peer nodes as a
notification. They will not proceed until they have all the
notifications they need for the current tick. The order delay
compensates for network latency. Thus, each peer node computes exactly
the same simulation in its entirety.–
Marc A. Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.