Mirage Source
Optimized Main Loop, Tizela - Printable Version

+- Mirage Source (https://mirage-engine.uk/forums)
+-- Forum: Mirage Source (Nostalgia) (https://mirage-engine.uk/forums/forumdisplay.php?fid=61)
+--- Forum: Archive (2006-2011) (https://mirage-engine.uk/forums/forumdisplay.php?fid=18)
+---- Forum: Resources (https://mirage-engine.uk/forums/forumdisplay.php?fid=49)
+---- Thread: Optimized Main Loop, Tizela (/showthread.php?tid=1190)



Optimized Main Loop, Tizela - Tizela - 15-08-2007

I saw there were some other guy that did this, mine might be better, migth not. Also I havn't really looked through the Mirage Engine Source that much so this might not be complete but anyone knowing what I'm talking about should easily get this to work.

Add this under any global scope
Code:
Public   OnlinePlayerID(0 to MAX_PLAYERS) as integer
The OnlinePlayerID array will keep track of every player that's online and is on your map. This simply becasue its used throughout the mainloop.


Add this in the sub GameLoop, before the do while..
Code:
dim c as long

Code:
Do While InGame
        Tick = GetTickCount

Right after this (client side atleast) add this

Code:
For i = 1 To C
         OnlinePlayerId = 0
     Next i

Code:
c  = 0
    For i = 1 To MAX_PLAYERS
         If IsPlaying(i) And GetPlayerMap(i) = GetPlayerMap(MyIndex)Then
               OnlinePlayerID(C) = i
               C = C + 1
         End If
     Next i

Now we loop through all the players and find all online, and on our map and we place them in the right order in to our OnlinePlayerID array.

Then replace every
Code:
For i = 1 To MAX_PLAYERS
            If IsPlaying(i) Then
                Call BltPlayer(i)
            End If
        Next i

with

Code:
For i = 1 To MAX_PLAYERS
            If OnlinePlayerID(i) = 0 Then
                Exit For
            End If
            Call BltPlayer(OnlinePlayerID( i ))
        Next i


then

Code:
For i = 1 To MAX_PLAYERS
            If IsPlaying(i) And GetPlayerMap(i) = GetPlayerMap(MyIndex) Then
                Call BltPlayerName(i)
            End If
        Next i

to

Code:
For i = 1 To MAX_PLAYERS
            If OnlinePlayerID(i) = 0 Then
                Exit For
            End If
            Call BltPlayerName(OnlinePlayerID( i ))
        Next i

Looks like it loops through the entire player array, but it don't. As soon as it find the first empty integer of our OnlinePlayersID it quits the loop.

Also, change all these puppies too
Code:
For i = 1 To MAX_PLAYERS
                If IsPlaying(i) Then
                    If GetPlayerMap(i) = GetPlayerMap(MyIndex) Then
                        If (GetPlayerX(i) = GetPlayerX(MyIndex)) And (GetPlayerY(i) = GetPlayerY(MyIndex) - 1) Then
                            CanMove = False
                        
                            ' Set the new direction if they weren't facing that direction
                            If d  DIR_UP Then
                                Call SendPlayerDir
                            End If
                            Exit Function
                        End If
                    End If
                End If
            Next i


to something like this

Code:
For i = 1 To MAX_PLAYERS
                If OnlinePlayerID(i) = 0 Then
                    Exit For
                End If
                        If (GetPlayerX(OnlinePlayerID(i)) = GetPlayerX(MyIndex)) And (GetPlayerY(OnlinePlayerID(i)) = GetPlayerY(MyIndex) - 1) Then
                            CanMove = False
                        
                            ' Set the new direction if they weren't facing that direction
                            If d  DIR_UP Then
                                Call SendPlayerDir
                            End If
                            Exit Function
                        End If
                    End If
            Next i
Again we can remove 2 if checks, since we know all players in this array is on our map, and is also online. Again exit the for loop if we reach the end.

Note! While I havn't treid this exact code out, I did something simlar with a 3.0.3 source I played around with, this hasn't been compiled there may be typos

Further Optimizing
Instead of looping through the players on your map to check if they still are there every frame then clearing it as my tutorial now does you can simply update it when people joins / enters the map. Thanks Robin for suggesting it. However, the vanilla MSE doesn't have a such function/packet and I'm to lazy to write one for you.


Re: Optimized Main Loop, Tizela - Robin - 15-08-2007

Haha, nice. I've been adding this to most of my games but never got around to writing a tutorial. Seems like yours will actually run a lot better than the code I made does.

Very nice.


Re: Optimized Main Loop, Tizela - Tizela - 15-08-2007

Thanks a bunch. I'll add a bit more optimazation and feature tutorials later for fun. Think I'll go for a "paint style fill tool" for the mapeditor next if there isn't a tutorial for that already.


Re: Optimized Main Loop, Tizela - Robin - 15-08-2007

There isn't. Although it has been done before.

All you need to do is a quick check on all connecting tiles if they're the same and fill them accordingly ;D


Re: Optimized Main Loop, Tizela - Tizela - 15-08-2007

Hehe, sure, but if you want to use line scans methods the code gets slightly more complex, but line scan methods uses far less levels of recussion than a pixel scan method. And I did a line scan function for my visual basic mapeditor I could post.


Re: Optimized Main Loop, Tizela - Robin - 15-08-2007

Couldn't you do something like this?

All 8 tiles connected to the one clicked are scanned. If they share the same tile number they are filled and a new scan is initalised on that tile, and so the scan spreads out until no more tiles are found sharing the same tile number?


Re: Optimized Main Loop, Tizela - Tizela - 15-08-2007

Your thinking of something like this. Though you do no't want to check all 8 tiles, since its not supposed to leak at corners.

sub filltiles(x,y, filltile,seedtile)
If seedtile = GetTile(x, y) Then
ChangeTile x, y, fill
Call filltiles(x - 1, y, filltile,seedtile)
Call filltiles(x + 1, y, filltile,seedtile)
Call filltiles(x, y - 1, filltile,seedtile)
Call filltiles(x, y + 1, filltile,seedtile)
end if
end sub

And that is indeed a fully working fill algoritm, but its also weak. (Thats point fill). Since it calls itself 4 times every time you call it, it recussion like hell and if you fill large areas you easily overflow the stack. If this was aplied to and empty 3x3 grid the recussion pattern would end like this.

Recussion 10
2-2-2
1-3-2
1-1-1

Each tile visited way more times than nessesary. When scaling that a bit it easily overflows the stack. It's probably okay for most Mirage Source users but my mapeditor should be able to handle 5000x5000 maps hehe.


Re: Optimized Main Loop, Tizela - Robin - 15-08-2007

Tizela Wrote:Your thinking of something like this. Though you do no't want to check all 8 tiles, since its not supposed to leak at corners.

sub filltiles(x,y, filltile,seedtile)
If seedtile = GetTile(x, y) Then
ChangeTile x, y, fill
Call filltiles(x - 1, y, filltile,seedtile)
Call filltiles(x + 1, y, filltile,seedtile)
Call filltiles(x, y - 1, filltile,seedtile)
Call filltiles(x, y + 1, filltile,seedtile)
end if
end sub

And that is indeed a fully working fill algoritm, but its also weak. (Thats point fill). Since it calls itself 4 times every time you call it, it recussion like hell and if you fill large areas you easily overflow the stack. If this was aplied to and empty 3x3 grid the recussion pattern would end like this.

Recussion 10
2-2-2
1-3-2
1-1-1

Each tile visited way more times than nessesary. When scaling that a bit it easily overflows the stack. It's probably okay for most Mirage Source users but my mapeditor should be able to handle 5000x5000 maps hehe.

Ah, I see.

But why 5000x5000 maps? Wouldn't it be more practical to simply use smaller maps but make them seamless rather than sharding the large map?


Re: Optimized Main Loop, Tizela - Tizela - 16-08-2007

Thats all in how you load them. My game will use maps more like regions, large exteriorcells so I only load what I need to see anyway basiclly.


Re: Optimized Main Loop, Tizela - Reece - 16-08-2007

What mappers want is a copy and paste tool, where they can select a section on any map, and paste it on another map/ the same map.


Re: Optimized Main Loop, Tizela - Matt - 16-08-2007

Renegade Wrote:What mappers want is a copy and paste tool, where they can select a section on any map, and paste it on another map/ the same map.

That would just make the maps the same, which would be pointless.. imo.

I'd fire any mapper who did that. Wink


Re: Optimized Main Loop, Tizela - Tizela - 18-08-2007

Hehe, I'll see what I'll put together. Smile I'll post it around the 24th. I'm way too stupid for my own good. .


Re: Optimized Main Loop, Tizela - Rezeyu - 18-08-2007

But.. it is the 17th...

Confusedhock: