code logs -> 2007 -> Fri, 20 Apr 2007< code.20070419.log - code.20070421.log >
--- Log opened Fri Apr 20 00:00:53 2007
00:40
<@McMartin>
I'm not sure what you mean by "metaprogramming" in your question, so I can't answer it
01:08 Mahal [~Mahal@Nightstar-12512.worldnet.co.nz] has quit [Quit: Leaving]
01:25 ReivSLEP is now known as Reiver
01:31 MyCatEats is now known as MyCatVerbs
01:31
< Janus>
Lordy... I need some advice on a wide-wide subject.
01:32
< Attilla>
How wide?
01:33
< Janus>
Game loops.
01:33
<@McMartin>
Advice implies a problem.
01:33
< Janus>
There's a problem~
01:34
<@McMartin>
"Game loops" isn't a problem.
01:34
<@McMartin>
"My game loopi sn't working" is one, as is "I know nothing about how to organize one", but the latter suggests different kinds of answers
01:37
<@gnolam>
So... what /is/ the problem, Janus?
01:37
<@gnolam>
(Highlighting for effect!)
01:37
<@McMartin>
Lacking a problem, my advice is that only the main thread gets to touch the video.
01:38
< Janus>
I guess it's the latter... It's just that... *thinks of a way to explain it effectively.*
01:41
<@gnolam>
It looped so fast it produced a positive feedback loop that, thanks to the immense power consumption and the accidentally perfect harmonics, ripped open a hole in space-time that threatens to consume the Earth within 72 hours?
01:42
<@gnolam>
If not, I have no idea what to do.
01:42
<@gnolam>
;-)
01:43
<@McMartin>
First. Fixed framerate or flexible?
01:43
< Janus>
Flexible. *still tinkering with it*
01:43
<@McMartin>
OK
01:43
<@McMartin>
Your basic loop looks like this:
01:43
<@McMartin>
forever {
01:44
<@McMartin>
Determine how much time has elapsed since the last frame
01:44
<@McMartin>
Read the input
01:44
<@McMartin>
Advance the world model the amount necessary for the time given
01:44
<@McMartin>
Render the screen
01:44
<@McMartin>
{
01:44
<@McMartin>
Er, }
01:45 * gnolam preferse fixed logic rates. Less flexibility, but so much less of a hassle.
01:45
<@gnolam>
-e
01:45
<@McMartin>
You will probably want to make that first one "determine how much time has elapsed, and if it's less than a certain amount, sleep long enough to make it be that amount, then remeasure"
01:45 Mahal [~Mahal@Nightstar-12512.worldnet.co.nz] has joined #Code
01:45 mode/#code [+o Mahal] by ChanServ
01:45
<@McMartin>
gnolam: Still leaves open how you handle frameskip.
01:46
<@McMartin>
You can livelock yourself with astonishing ease.
01:46
<@gnolam>
if (frames_behind > frameskip_amount) { frames_behind = 0; tell_the_user_to_upgrade_seriously_(); }
01:46
< Janus>
Alright, I think I got it! My problem is that... I know how to make a loop where the world model follows the same rules consistantly, like an FPS. But I'm a little confused about how to make one where the input, rules, etc. change depending on the situation, like a ... turn-based card game. (grasping for genres there.)
01:47
<@McMartin>
You need to make "update the world" not be the same function all the time, either by reassigning a function pointer or having some variable indicatating what mode the game is in.
01:47
<@McMartin>
If you're at the main menu, for instance, "the world" is basically "what thing is selected" and the world model is "arry keys or the joystick move the selection"
01:48
<@McMartin>
s/arry/arrow/
01:48
<@gnolam>
If you're OOPing, the former is a pretty good application for the strategy pattern.
01:48
<@McMartin>
If you aren't, a state machine is the way to go.
01:48
<@McMartin>
Arguably, even if you are a state machine is The Win.
01:49
<@McMartin>
UQM is Not The Way To Do It.
01:50
<@McMartin>
If we ever feel like totally rewriting the entire leeging game logic, we have some plans for State Machine Of Doom, but they're not terribly well-designed ones.
01:50
< Janus>
I believe I am. The "world model" is actually where one of the objects has their update() method called. Also, my game loop looks almost exactly like yours, Martin.
01:50
<@McMartin>
(UQM uses huge amounts of threading and uses the procedure stack for context. Don't Do This (tm))
01:50
<@gnolam>
Ick.
01:51
<@McMartin>
(It's cleaner than it used to be, though!)
01:51
<@McMartin>
(There's something to be said for having a state stack, especially for something RPG-like with loads of context menus)
01:51
<@McMartin>
(But.)
01:51
<@gnolam>
(Why are we whispering?)
01:52
<@McMartin>
Janus: Have a class for Game Mode, subclassed for each kind of mode the game can be in.
01:52
<@McMartin>
Reassign some global to indicate mode, or have the updateframe method return the mode object that should be used next frame.
01:52
<@McMartin>
And have those mode objects be Singletons.
01:53
<@McMartin>
In C, I'd do this with an enum used to index an array of function pointers.
01:53
< Janus>
Would... having a switch/case thingy work there?
01:53
<@McMartin>
Yes, that too would work.
01:53 Mahal [~Mahal@Nightstar-12512.worldnet.co.nz] has quit [Quit: Leaving]
01:53 Mahal [~Mahal@Nightstar-12512.worldnet.co.nz] has joined #Code
01:53 mode/#code [+o Mahal] by ChanServ
01:53
<@McMartin>
Though the enum/array of fnpointers is probably more efficient.
01:53
<@McMartin>
On the third hand, this code is running, at most, 100 times a second.
01:53
<@McMartin>
You can spare the cycles =P
01:55
<@McMartin>
If you are in fact doing something turn-based, though, you're probably best off fixing the framerate at 30.
01:55
<@gnolam>
I'd put it higher. Fluid animation FTW.
01:55
<@McMartin>
That way you don't have to include a time unit argument.
01:55
<@McMartin>
... Film is 18.
01:55
<@gnolam>
... 18?
01:56
<@McMartin>
NTSC television is 30 after you take interlacing into account.
01:56
<@gnolam>
24/25, with motion blur.
01:56
<@McMartin>
PAL is 25.
01:56
<@gnolam>
The latter is important.
01:56
< Janus>
I have to draw my own animations, so it'll be as fluid as igneous rock.
01:56
< Janus>
Regardless of framerate~
01:56
<@McMartin>
More to the point, if you want fluid animations, you must use variable framerate or your userbase will kill you.
01:56
<@McMartin>
And you probably need to do kinematics, etc.
01:57
<@McMartin>
60 is "traditional"
01:57
<@McMartin>
But that frame rate was often halved in practice.
01:57
<@McMartin>
UQM's varies between 25 and 35 depending on what you're doing.
01:58
<@McMartin>
But for any given activity it's fixed.
01:58
< Janus>
(... How come framerates are usually around 60 like that, anyway?)
01:58
<@gnolam>
Eh, you don't have to go all interpolatey. It's just that 30 is a /low framerate/.
01:58
<@gnolam>
Janus: traditional refresh rate.
01:58
<@McMartin>
Televisions refresh based on AC power oscillation.
01:59
<@McMartin>
Which is 60Hz in North America, and 50Hz in Europe.
01:59
<@McMartin>
TVs are also interlaced, so actual frame rate is half that.
01:59
<@gnolam>
If you have resolution >= , say, 640x480 and/or fast-moving objects... that low rate will show.
02:00
<@McMartin>
And if you require the ability to pixel-render 1024x768 85 times a second, your sysreqs are ridiculously artificially high
02:00
<@McMartin>
Which is why dynamic framelength computation becomes mandatory.
02:02
<@McMartin>
You also have to worry about clipping through objects at very low framerates, but that's neither here nor there.
02:02
< Janus>
Heh, until now, I just plopped a "past_t = t; t = SDL_Tick();" at the beginning of a loop, and try oh so hard to keep it high.
02:02
<@McMartin>
For Fixed Frame Rate you want something like SleepThreadUntil.
02:02
<@McMartin>
For those kinds of things, UQM is a useful model.
02:03
< Janus>
Would something like that free up the CPU? I've noticed that when I run things I've made, they hog up whatevers available ruthlessly.
02:03
<@McMartin>
target = past_t + (frame length in ms) - SDL_Tick(); if target >= 0 SDL_Delay(target)
02:03
<@McMartin>
Yes.
02:03
<@McMartin>
You must yield once a frame.
02:04
<@McMartin>
In particular, rendering more often than the refresh rate is utterly pointless
02:04
<@McMartin>
After the call to SDL_Delay() you then reassign past_t
02:04 * ToxicFrog upreads
02:05
<@ToxicFrog>
Last time I did this, "update the world model" was "traverse the object chain and call the :update method on each object"; the last object in the chain was responsible for redrawing the screen. This meant you could switch between menus, main game, etc just by switching object chains.
02:06
<@McMartin>
This implies the existence of an object chain, of course~
02:06
<@McMartin>
Those are also nice because you can save state by serializing all the chains.
02:08
< Janus>
It's a very small model, with three objects total. One for the 'world', two for two characters, and perhaps two more as the two characters inherit a PC or a NPC object. (or those inherit them, or some such.)
02:09
< Janus>
Those two character objects are also members of the world object. So only one update method needs to be called.
02:09
<@McMartin>
It should always be the case that only one update method needs to be called.
02:09
<@McMartin>
If not, you're missing a level of abstraction, to wit, a Game Mode object.
02:10
<@McMartin>
You basically need multiple worlds; one for the Main Menu, one for the Game, etc.
02:10
<@McMartin>
You can select it with a switch/case, or by reassigning a local variable, or by reassigning a global, but the basic concept remains the same.
02:12 gnolam [lenin@Nightstar-13557.8.5.253.se.wasadata.net] has quit [Quit: Z?]
02:12
< Janus>
What if it's not that divided though..? Like, say, the difference between where the player and NPC enter their commands, and then those said commands are executed.
02:12
<@McMartin>
Then you haven't divided your model finely enough.
02:13
<@McMartin>
You can change "the world" once per frame, here.
02:13
<@McMartin>
"Player is entering commands" and "NPC is simulating commands being entered" are different "worlds" here.
02:14
<@McMartin>
Alternately, the "world" is carrying extra state of its own indicating what mode it's in and it does another layer of transforming (ignoring input when the NPC's selection is displayed, etc.)
02:14
< Janus>
Okay, I'm starting to see now.
02:16
< Janus>
Alright! Thanks for your help then! I'm always forgetting about how useful abstraction is.
02:17
<@McMartin>
Spending time in the guts of game code helps too.
02:17 * McMartin found some lovely bit-level evil in Gradius's game loop.
02:19 * Janus shots it in the core.
02:21 Janus is now known as Jan[bathipoo]
02:44 Raif [~corvusign@Nightstar-22484.hsd1.ca.comcast.net] has joined #Code
02:44 mode/#code [+o Raif] by ChanServ
03:43 Jan[bathipoo] is now known as Janus
04:03 Janus [~Cerulean@Nightstar-10302.columbus.res.rr.com] has quit [Quit: So I poured it into my hand to see if it was empty. It is now.]
04:15 MyCatVerbs is now known as MyCatSleeps
04:20 You're now known as TheWatcher
06:05 Vornicus-Latens is now known as Vornicus
06:34 Syloqs-AFH [Syloq@NetAdmin.Nightstar.Net] has quit [Connection reset by peer]
06:53 AD[Laptop] [~farkoff@Nightstar-29204.neoplus.adsl.tpnet.pl] has joined #Code
06:56 AD[Laptop] is now known as AnnoDomini
07:25 AnnoDomini [~farkoff@Nightstar-29204.neoplus.adsl.tpnet.pl] has quit [Quit: AWAY!]
07:28 Reiver is now known as ReivAFK
08:15 You're now known as TheWatcher[afk]
09:19 gnolam [lenin@Nightstar-13557.8.5.253.se.wasadata.net] has joined #Code
09:19 mode/#code [+o gnolam] by ChanServ
10:07 You're now known as TheWatcher[wr0k]
10:32 Chalcedon [Chalceon@Nightstar-6297.dialup.ihug.co.nz] has joined #code
10:32 mode/#code [+o Chalcedon] by ChanServ
10:36 Chalcedon [Chalceon@Nightstar-6297.dialup.ihug.co.nz] has quit [Ping Timeout]
10:36 AD[Laptop] [AnnoDomini@62.108.180.ns-23472] has joined #Code
10:41 AD[Laptop] [AnnoDomini@62.108.180.ns-23472] has quit [Quit: BRB. Plugged the mouse in too late and now the roller is non-functional.]
10:43 AD[Laptop] [AnnoDomini@62.108.180.ns-23472] has joined #Code
10:53 gnolam is now known as gnolam|away
11:15 ReivAFK is now known as Reiver
12:29 gnolam|away is now known as gnolam
12:43 Thaqui [~Thaqui@Nightstar-25849.jetstream.xtra.co.nz] has quit [Connection reset by peer]
13:20 AD[Laptop] [AnnoDomini@62.108.180.ns-23472] has quit [Quit: Going hunting for Snickers bars.]
13:30 Mahal is now known as MahalBEDD
15:30 * ToxicFrog kills both MS Access and MDBTools with a fork
15:37 You're now known as TheWatcher[afk]
15:43 * MyCatSleeps idly follows up by vapourising their corpses with an ion cannon.
15:44 MyCatSleeps is now known as MyCatVerbs
16:28 * ToxicFrog ...s at windows
16:28
<@ToxicFrog>
So, drag and drop apparently sets PWD to some random whack-ass value that is usually, but not always, $HOME.
16:30
<@Reiver>
?
16:31
<@Vornicus>
by drag and drop I assume you mean dragging a file onto a program
16:32
<@ToxicFrog>
Yeah.
16:33
<@ToxicFrog>
For example, I drag s:/Source/evarchive/test.csv onto s:/Source/evarchive/evarchive.exe
16:33
<@ToxicFrog>
$PWD is c:/Home/ben/
16:33
<@Vornicus>
You get the full paths of the things being thrown around, right?
16:34
<@ToxicFrog>
Yeah, which doesn't help when I'm trying to load supporting files from ./
16:34
<@Vornicus>
ah, true
16:34
<@Vornicus>
you may wish to issue a chdir
16:34 * ToxicFrog fiddles with getting at argv[0] from lua
16:39 Reiver is now known as ReivZzz
16:53
<@Pi>
Have you instead tried loading supporting files from /. ?
17:07 ReivZzz is now known as ReivSLEP
17:15 KarmaBot [~karma.bot@Nightstar-29204.neoplus.adsl.tpnet.pl] has quit [Connection reset by peer]
17:16 KarmaBot [~karma.bot@Nightstar-29204.neoplus.adsl.tpnet.pl] has joined #Code
17:16 You're now known as TheWatcher
17:49 You're now known as TheWatcher[afk]
17:57 AD[Laptop] [~farkoff@Nightstar-29204.neoplus.adsl.tpnet.pl] has joined #Code
18:00 AD[Laptop] is now known as AnnoDomini
19:00 You're now known as TheWatcher
19:13 Syloq [Syloq@NetAdmin.Nightstar.Net] has joined #code
19:28 KBot [~karma.bot@Nightstar-29708.neoplus.adsl.tpnet.pl] has joined #Code
19:29 AnnoDomini [~farkoff@Nightstar-29204.neoplus.adsl.tpnet.pl] has quit [Ping Timeout]
19:30 KarmaBot [~karma.bot@Nightstar-29204.neoplus.adsl.tpnet.pl] has quit [Ping Timeout]
19:30 KBot is now known as KarmaBot
19:36 AD[Laptop] [~farkoff@Nightstar-29708.neoplus.adsl.tpnet.pl] has joined #Code
20:34 Syloq is now known as Syloqs-AFH
20:49 MyCatVerbs is now known as MyCatEats
21:01 Janus [~Cerulean@Nightstar-10302.columbus.res.rr.com] has joined #Code
21:58 Chalcedon [Chalceon@Nightstar-6297.dialup.ihug.co.nz] has joined #code
21:59 mode/#code [+o Chalcedon] by ChanServ
22:24 Chalcedon [Chalceon@Nightstar-6297.dialup.ihug.co.nz] has quit [Quit: ]
22:41 You're now known as TheWatcher[T-2]
22:45 You're now known as TheWatcher[zZzZ]
22:53 MyCatEats is now known as MyCatVerbs
23:26 MahalBEDD is now known as Mahal
23:45 Chalcedon [~Chalceon@Nightstar-2104.ue.woosh.co.nz] has joined #code
23:45 mode/#code [+o Chalcedon] by ChanServ
23:53 AD[Laptop] [~farkoff@Nightstar-29708.neoplus.adsl.tpnet.pl] has quit [Quit: OBJECTION!]
23:59
< MyCatVerbs>
Whoa, crap on a crutch.
23:59
< MyCatVerbs>
GHC produces big executables.
23:59
<@Vornicus>
GHC?
--- Log closed Sat Apr 21 00:00:04 2007
code logs -> 2007 -> Fri, 20 Apr 2007< code.20070419.log - code.20070421.log >