sandbox games - how???

Blitz3D Forums/Blitz3D Beginners Area/sandbox games - how???

chwaga(Posted 2007) [#1]
how do you make a sandbox game, without it lagging to death over all the variables???

this is what I have so far :
SeedRnd MilliSecs()
SetBuffer BackBuffer()
Type sand

Field x
Field y
Field colors
End Type 

Graphics3D 1024, 768, 32, 1

Repeat
RenderWorld()

If MouseDown(1) Then

s.sand = New sand 
s\x = MouseX()
s\y = MouseY()
s\colors = Rnd(0, 100000)

EndIf 

For s.sand = Each sand

LockBuffer FrontBuffer()
WritePixel s\x, s\y, s\colors
UnlockBuffer FrontBuffer()

s\y = s\y + 1


If s\y > 1023 Then Delete s

Next 





Flip 
Cls 
If KeyHit(57) Then Cls 



Until KeyHit(1)

End 


how do I make it go fast when under larger amounts of "sand grains"


Sledge(Posted 2007) [#2]
Lock/unlock your buffer outside of the For...Next loop & use WritePixelFast. (EDIT: Pixel work will never operate objectively 'fast' under B3D but you can at least make it less slow.)


chwaga(Posted 2007) [#3]
doh!


chwaga(Posted 2007) [#4]
i feel like an idiot now, thanks :)

but there's one more problem, I'm getting a mem access error if i click while the game is running in windowed mode.


chwaga(Posted 2007) [#5]
furthermore, sandbox games often can handle hundreds of thousands of sand co-ords, I start lagging up around 1000 grains,


Sledge(Posted 2007) [#6]
I'm getting a mem access error if i click while the game is running in windowed mode

Switch to locking/unlocking the backbuffer instead of the frontbuffer.


Sledge(Posted 2007) [#7]
furthermore, sandbox games often can handle hundreds of thousands of sand co-ords, I start lagging up around 1000 grains

http://dbfinteractive.com/index.php?topic=2112.msg30640#msg30640


chwaga(Posted 2007) [#8]
?


Yo! Wazzup?(Posted 2007) [#9]
I didn't get it either...


Sledge(Posted 2007) [#10]
Writepixelfast() isn't fast at all so you will find your programs slowing down long before you can write a screen's worth of pixels at contemporary resolutions -- the link simply offers an explanation why. You might even find some links to faster pixel libraries in that thread.

While I'm posting I'll also mention that, these days, calling a game 'sandbox' means something very specific that does not involve grains of sand.


Yo! Wazzup?(Posted 2007) [#11]
Yeah - that's what I thought chwaga meant when I read the title...


chwaga(Posted 2007) [#12]
I was talking about sand-dropping games :)

also, it's not the drawing time that's slowing it down, look at this:

Graphics 1024, 768, 32, 1

LockBuffer FrontBuffer()
Repeat

WritePixelFast Rnd(2, 1022), Rnd(2, 766), Rnd(0, 10000)

Until KeyHit(1)
UnlockBuffer FrontBuffer()


it seems that the amount of types in the scene is what's bogging it down.


Sledge(Posted 2007) [#13]
it seems that the amount of types in the scene is what's bogging it down.

I'm not sure what the code you posted is supposed to prove. Of course the more type instances you have [to iterate through] the longer it's going to take, but a writepixelfast() operation for each instance is only going to slow things even further. It's an expensive operation:



Notice there that I'm passing WritePixelFast a set of integers rather than floats (which is what rnd produces) also -- it's a good habit to minimise type conversion for speed critical operations.


SLotman(Posted 2007) [#14]
this should be pretty fast:

SeedRnd MilliSecs()
SetBuffer BackBuffer()

Type sand
	Field x%
	Field y%
	Field colors%
End Type 

Graphics3D 640, 480, 32, 2

Repeat

   If MouseDown(1) Then
	s.sand = New sand 
	s\x = MouseX()
	s\y = MouseY()
	s\colors = Rnd(0, 100000)
   End If 

   If frame Mod 2 Then 
	LockBuffer BackBuffer()
	For s.sand = Each sand
		WritePixel s\x, s\y, s\colors
		s\y = s\y + 1
		If s\y > GraphicsHeight()-1 Then Delete s
	Next 
	UnlockBuffer BackBuffer()
	Flip False
	Cls 
   End If

   frame=frame +1
   If frame > 1 Then frame=0

Until KeyHit(1)

End 



chwaga(Posted 2007) [#15]
cool, how'd you do it? (I'm not getting the code)


Sledge(Posted 2007) [#16]
Flip False stops your code being constrained by the monitor's vertical refresh rate. All the speed increase in that code comes from flipping false.

The Frame gubbins is weird and, I presume, there as a method to slow the falling rate down without using a float for s\y (if SLotman was trying to draw every other frame of movement then that's not what his code does). Mod is expensive compared to a straightforward value comparison (=) I believe and I'm not sure why he opted for it.


SLotman(Posted 2007) [#17]
Mod is not that expensive (at least not 1 MOD), and you can change it to MOD 3, MOD 5 or whatever. You could use "if frame=0", I guess I just wrote it pretty fast and MOD was the first thing on my mind.

This speed things up because it's not processing and drawing all the sand on every loop -- flip false was just an extra boost to it, as it was reducing the resolution to 640x480 ;)


Sledge(Posted 2007) [#18]
This speed things up because it's not processing and drawing all the sand on every loop

Actually, because you only ever update the sand's position in the same conditional block that you draw it, you're really slowing things down very fractionally. You might've intended a frameskip but a frameskip that is not.


chwaga(Posted 2007) [#19]
OK, now, how do I check if the pixel directly below the "sand grain" is black?


b32(Posted 2007) [#20]
With ReadPixel(Fast) ? When I need to do this, I read a black pixel from the display, and store it in a variable, because the values of ReadPixel(Fast) could vary on different bitdepths.
Sort of like this:(pseudocode)
Graphics 800, 600, 0, 2
SetBuffer BackBuffer()

black = ReadPixel(0, 0)

.. other stuff..

(in main loop:)
   if ReadPixel(x, y) = black then .. etc
With the sand grain it would be something like (x, y + 1), where (x,y) is the grains position.


chwaga(Posted 2007) [#21]
what is black on 32 bit?? For some reason on the code:



If you'll run it, you'll notice that when pressing the mouse, the dropping pixels are distributed between two points, one: the mouse co-ords, two: mousey, mousey

--????


b32(Posted 2007) [#22]
Maybe it is safer to do this:
LockBuffer BackBuffer()
Global black = ReadPixelFast (0, 0)
UnlockBuffer BackBuffer()

About the two 'dropping points', there is a typo on this line:
		Else If ReadPixelFast (s\x+1, s\y) = black Then 
		s\x = s\y+1
It should be s\x=s\x+1
Oh .. and black seems to be -16777216 when I try it on 32-bit


chwaga(Posted 2007) [#23]
lol, ok thanks


chwaga(Posted 2007) [#24]
ok, take for example, this:



when the sand grains reach the bottem of the triangle "pit", they simply dissappear, where are they going?


Sledge(Posted 2007) [#25]
Don't worry about different bit-depths... black will always be $0 anyway.

Okay, a few things:

Read up on converting between integer and hex colour values here;

I can't run your example code because everything is hard-coded to a resolution my screen does not support. I'm guessing you're trying to do something similar to what I did here though. Should help.

OK, now, how do I check if the pixel directly below the "sand grain" is black?
As has been said, ReadPixel(Fast) is the boy. Seeing as I was tapping out an example while b32 snook in I'll post it anyway (some image buffer work in here too):



b32(Posted 2007) [#26]
:( sorry sledge ..


chwaga(Posted 2007) [#27]
It wasn't that hard-coded, try this: (I modified 4 lines of code...)




chwaga(Posted 2007) [#28]
by the way, your supplied program (the hex one) can be generated in 92 millisecs with locked image buffers, up against 13115 millisecs without locked buffers...


Sledge(Posted 2007) [#29]
Yep there's no buffer locking in the example for clarity, but you should lock and use the 'fast' pixel commands for release code. Personally I would indent between locking and unlocking so you don't forget to do the latter.

:( sorry sledge ..

:D


chwaga(Posted 2007) [#30]
K...back to the original point of the thread...

Where do the grains go once they reach the bottom of the "pit"??


Sir Gak(Posted 2007) [#31]
Has anyone ever posted a library routine that replaces WritePixelFast with something that writes REALLY fast?

Other programming languages apparently can write a screen-full of pixels fast (ie in real time), so why can't Blitz using an external dll?


chwaga(Posted 2007) [#32]
the pixel drawing isn't what takes so long, It's the reading and transforming the pixels that takes so long


JBR(Posted 2007) [#33]
chwaga, not sure what sandbox style game is but it sounds like you have particles falling & collecting.

Is this what you want?

Jim


chwaga(Posted 2007) [#34]
Kinda, It's like a sand-falling game where you can drop sand particles, kinda like this


chwaga(Posted 2007) [#35]
any help??


Tranz(Posted 2007) [#36]
This might be more like what you're looking for, unlike water that seeks the lowest path, this sand can be piled up in spots.




chwaga(Posted 2007) [#37]
That kinda works, except, how do I prevent them from going into eachother?? I'll have like 1000 pixels with sand in them, but 8000 sand entities.


chwaga(Posted 2007) [#38]
nevermind, just have to put a small delay in, still, it's happening, not on such a large scale though