gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Problems with my Pong game(Download available)

#144533 - yellowstar - Sat Nov 03, 2007 3:40 pm

This topic is a continuation about
the issues with my wireless Pong game,
started in the wireless topic.

Don't post about helping with
this in the wireless topic.
Instead, post here.


Last edited by yellowstar on Mon Dec 24, 2007 10:24 pm; edited 5 times in total

#144536 - yellowstar - Sat Nov 03, 2007 3:57 pm

The following quotes are posts
about the original issues.

yellowstar wrote:

I am almost done with my Pong game.
All that's left is Wireless.(and bugs)
(By the way, scores are displayed in console
on sub screen, game on main.
Due to a problem with console not working
on main.)
(Will implement non-console scores later.)

The opponet's bat
is choppy.(On the recieving DS.)

Other things are out of sync,
but that's my problem.
(Only bat movement messages are sent
at the moment)

EDIT:
I am using R 60.
Has the aforementioned problems
been resolved?

EDIT2:
There are more problems.

Sometimes,
the opponets bat(on the recieving DS)
would be behind.
It would still follow the wanted movement.

In the worst case,
the opponets bat
wouldn't move at all.

EDIT3:
Another problem:

Sometimes there is some lag.
Both DSes,(at least I think it's both)
slow down.
The max is about one second.

(By the way,
I got the scores in sync.)
(They don't get updated at exactly
the same moment.)


melw wrote:

You need to be prepared for choppy networking. It doesn't matter what the reason is. Even if the lobby library was 100% perfect, for example the users can be too much apart from each other or there's other traffic on the channel distracting the sent messages.

To the actual question - how to achieve smooth gameplay in your case? There's a handful of options you can choose from:


- synchronize time between the DS's in the beginning and timestamp your messages.
- interpolate the movement between frames
- don't send data every frame, rather send when something happens (bat starts moving/stops, hits a ball, etc.), and also then send game parameters (bat speed, ball speed, ball direction), not just static values (bat/ball coordinates). this makes interpolating values a lot easier. in between you can sync the data just to be sure.
- draw stuff on screen with couple frames of lag compared to your actual gametime to allow the other end to catch up.


btw. I once did a Pong for Series 60 phones using Bluetooth (one of the most horrifyin coding experiences in my life :) That was the wonkiest networking I've dealt with, now doing things with the lobby lib life seems whole lot of easier...


yellowstar wrote:

It's obvious I never did any networking stuff
before...(I read I few tutorials,
but I couldn't actually do them due to
no network and Dial-Up.)

I'll try your suggestions melw,
and if those fail,
I guess I'll search gamedev and the Internet.


yellowstar wrote:

Thanks melw.
Thanks to your second suggestion,
I have gotten the bats to
move smoothly now.

Now,
I'm having troubles with scores
being out of sync.
(Hopefully I can figure it out.
If not, I'll try searching the Inet.)


MechaBouncer wrote:

That's certainly odd. I would think it would be simple enough to sync them up each time a player scored since you have to wait a little anyway. Is it something that alternates between players or is one keeping correct score consistently while the other side is not?


Mighty Max wrote:

Well, i guess he is playing a game on both DS and only correcting the positions on the other one.

@Yellowstar,
Let the hoster control the game. Do not calculate misses/hits and thus points on both DSes.



yellowstar wrote:

I think I fixed the out of sync scores.
(I can't be sure until I test it with somebody else)

The way I am doing it at the moment, is this:
No messages for scoring are sent.
Instead, both systems decide
when a point is scored,
based on where the bats and ball are.

This game is getting very
close to completion/release.(minus bugs and such)

EDIT:

@Mighty Max:
I was doing the latter...
I was having both systems
tell the other when it scored a point.



Mighty Max wrote:
yellowstar wrote:

The way I am doing it at the moment, is this:
No messages for scoring are sent.
Instead, both systems decide
when a point is scored,
based on where the bats and ball are.


Keep in mind that the ball's properties (position, direction, speed) and the bat's properties (position) are _never_ in complete sync. This setup will produce different results on both DSes by design on a real game (There will be the situation that one DS counts a score and on the other DS the ball was just catched)


yellowstar wrote:
Well,
that made the problem worse.(the score difference between
the systems were large.)

Time to come
up with a differen't mechism.


MechaBouncer wrote:
Perhaps you could handle it that when the ball is travelling in one direction, the player it's travelling to is handling the ball mechanics and sending position and direction information to the other DS, then it flips when going the other direction. That way, the person having to return the ball doesn't get screwed by the offhand chance that the ball position wasn't synched well enough. Does that sound reasonable?


Mighty Max wrote:
yellowstar wrote:

EDIT:

@Mighty Max:
I was doing the latter...
I was having both systems
tell the other when it scored a point.


You misunderstood me. Do NOT make both sides work the same. This will not work. There needs one instance that has the last word on all decisions. (It's just like persons, when they are both the same urge to have the last word, they will argue or going into a "whatever!" state ;) )

Have one and always the same DS counting the scores. Have the same DS deciding whether the ball was hit. Do not calculate the hit on the other DS for any other reason then to hide lag from the displaying (precalculation which is superseeded by the host)

#144537 - Lick - Sat Nov 03, 2007 4:06 pm

In your game, make a menu. The menu should at least have these 2 options:
1) Host ad-hoc game
2) Join ad-hoc game

When a player chooses to host, you run the server-code:
- listen for connecting players
- keep track of server's own paddle
- keep track of the ball (position and direction)
- calculate collisions
- keep track of the score
- send updates to the client

When a player chooses to join, you run the client-code:
- search for servers to join
- keep track of client's own paddle
- receive updates from the server (ball position/direction, server's paddle position and score)
- send updates to the server (own paddle position)
_________________
http://licklick.wordpress.com

#144538 - yellowstar - Sat Nov 03, 2007 4:16 pm

Here is the new problems:

(I tried to debug this,
but source unknown)
(This is probably a bug
in my code,
but I can't find the cause.)

(I am trying to have only
the host handle scoring,
and have it tell the client whenever
a score is made. The client dosen't decide
by itself when a score is made,
it relies on the host.)

On the client side,
nothing seems to move.
(On the host side,
the client's bat is moving.)
(I have found,
that this is because Reset is
being called ~15-27 times
per second.)(may not be accurate due to inaccurate timer setup.)
(Reset puts all the sprites back were they were,
like at the start of the game.)

The new scoring problem:
The client doesn't realize
that the host made a goal,
when it actually did.

However,
when the client makes
a goal,
it's score,
and the host's score,
are updated on the client.

(Also,
I have found that,
for some reason,
that the # of times
the client passes the GetScoreMessage,
is about the same as the # of calls to Reset.)
(The host isn't sending an abnormal number
of scoring messages.)
(GetScoreMessage checks for scoring messages,
and updates scoring, and then resets.)

EDIT:
By passing the GetScoreMessage function,
I mean it thinks there is a
score message, when there
actually isn't any.

@Lick:
I didn't see your post till now
Lick, since you posted
before I finished posting
this post.

#144552 - yellowstar - Sat Nov 03, 2007 7:32 pm

Maybe its a bug in the lib...

I'm trying to force it to work via hacking.

I got it to stop resetting all the time,
but I'm getting problems similar
to the second problem.

#144557 - Mighty Max - Sat Nov 03, 2007 8:58 pm

What is the "second problem"?
In which way would you think the lib is bugging (so i can have a look)?
_________________
GBAMP Multiboot

#144620 - yellowstar - Sun Nov 04, 2007 9:56 pm

The second problem:

yellowstar wrote:

The new scoring problem:
The client doesn't realize
that the host made a goal,
when it actually did.

However,
when the client makes
a goal,
it's score,
and the host's score,
are updated on the client.

(Also,
I have found that,
for some reason,
that the # of times
the client passes the GetScoreMessage,
is about the same as the # of calls to Reset.)
(The host isn't sending an abnormal number
of scoring messages.)
(GetScoreMessage checks for scoring messages,
and updates scoring, and then resets.)


I found problems on the host also.

I have found it is sending a max of 2 scoring messages
per second.(All of which are for the client, except for one exception)
It is constantly sending the score of the client,
even though it isn't making that many scores.
(These scores for the client are all the same,
except for one message for when it scores.)

The only time when the host's score makes it through,
is, when the client makes a goal.(the client's message makes it to)
(The host's score gets updated when the client scores)

The problem could be this:
The messages for the client's score
could be clogging out the host score.(all of
the time except when client scores)

I'm trying to fix it via hacking,
but I haven't gotten it to work at the moment.


As for the bug:(The number of messages per second
is alot more than what the host sends.)
This is a problem with the client.

Here's what's happening,
based on the debug file:

Basicly,
it's the same as the host,
except on the recieving end.(Except,
# of messages per second is about ~15-27)
The client is recieving the above number
of fake messages.(The only real ones are the messages
for the client's score, for when it changes.)
(Also, the scoring messages for the host.)
(The scoring messages for the host are only sent once.)

EDIT:
It would be great, if,
you, Mighty Max,
would add functionality to
the lib to capture packets on the current channel.
(Only messages sent by the apps using the lib,
not messages for the lib's internal stuff.)
(Like telling other system's that this DS is here,
rooms, ect.)
(It would capture broadcasted packets,
and packets not sent to it.)

#144623 - Mighty Max - Sun Nov 04, 2007 10:56 pm

Keep in mind that the callback might be triggered at any time out of system mode (IRQ) and that a SendTo might trigger a callback even if you are within an IRQ, as it is checking for data in the fifo.

If you are changing data you are already changing this is likely to make trouble (reentrancy)

Ive tried to provoke errors in the lib, but i was not able to get it to receive more messages as sent. If i came to a problem in the try to reproduce it, is that once the two DSes get out of sync in sent/gotten messages for a longer time (usually the gotten is a bit behind the sent amount), every no more ack-ed messaged are received at all.

Just to make sure, you are not using one of the reserved stream IDs? (0x7FFF,0xFFFF)

Quote:

EDIT:
It would be great, if,
you, Mighty Max,
would add functionality to
the lib to capture packets on the current channel.
(Only messages sent by the apps using the lib,
not messages for the lib's internal stuff.)
(Like telling other system's that this DS is here,
rooms, ect.)
(It would capture broadcasted packets,
and packets not sent to it.)


I got to disappoint you. This is no option.
The DS hardware does - to the current knowledge - not trigger a receive event message that are not addressed for the DS by either a group address or the specific mac address. It would be a really dirty hack to either use allways broadcasts (and filter by SW) or to use forensic methods to capture dropped-after-receive packets out of the mac memory

You could use a ralink card, or an PCap compatible WLan adapter with wireshark to get the raws for all mac addresses. Set the filter "eth.type==0x08fe"
_________________
GBAMP Multiboot

#144625 - yellowstar - Sun Nov 04, 2007 11:27 pm

Mighty Max wrote:


Just to make sure, you are not using one of the reserved stream IDs? (0x7FFF,0xFFFF)

I'm only using stream ID 1.
By the the way,
what is total number of streams?(minus the reserved ones)

Mighty Max wrote:

Quote:

EDIT:
It would be great, if,
you, Mighty Max,
would add functionality to
the lib to capture packets on the current channel.
(Only messages sent by the apps using the lib,
not messages for the lib's internal stuff.)
(Like telling other system's that this DS is here,
rooms, ect.)
(It would capture broadcasted packets,
and packets not sent to it.)


I got to disappoint you. This is no option.
The DS hardware does - to the current knowledge - not trigger a receive event message that are not addressed for the DS by either a group address or the specific mac address. It would be a really dirty hack to either use allways broadcasts (and filter by SW) or to use forensic methods to capture dropped-after-receive packets out of the mac memory

You could use a ralink card, or an PCap compatible WLan adapter with wireshark to get the raws for all mac addresses. Set the filter "eth.type==0x08fe"


Unfortunatly,
using a PC for this,
for me, is not an option.(Don't have any wireless NICs
in any of my PCs, and they are old)

I guess the only option would be
to write a packet capture app,(based on Juglak's WMB Host)
and have it only recognize user messages.

EDIT:
The only IRQs
I am using,
are, vblank and all timers.

Once the messages are sent,
they are not changed.

EDIT2:
I have successfully hacked
the host to only send the correct packets.(no fakes)
(I'm still having the above problems with scoring)
(clogging must not be the problem)

EDIT3:
The messaging is in sync.
That is, neither DS is behind the other in
sent/received messages.

#144777 - yellowstar - Wed Nov 07, 2007 2:30 am

Failed again.

I tried having the
host send sync messages.

These messages are sent every 3rd vblank.
These sync messages would
contain the host's bat y pos,
ball data, and the scores.
(the bat and ball data isn't
used on the client, since it wouldn't work right.)

The host sends the data(at least the scores)
correctly.

But,
the client dosen't coroperate.

The client's scores behave
similar to before,
except for a few new problems.(Sometimes
it would update, but one of the scores would
be really out of sync)(These times would be
when the client makes a goal)

I tried hacking,
but that didn't make much difference.

#144812 - melw - Wed Nov 07, 2007 9:44 pm

I was originally planning to spend this afternoon on something different, but oh well: pong nds+src

It's bit sketchy and not very playable (as in fun to play) but works over here both in local game mode and in ad-hoc mode with the lobby library. No interpolations or any fancy stuff included, in other words flaky network will stutter the gameplay.

Mighty Max, I first tried using rooms but the room owner not receiving all the user callbacks makes things somewhat complicated... Hope to see the missing callbacks being added to the library at some point.

#144813 - Mighty Max - Wed Nov 07, 2007 9:51 pm

melw wrote:

Mighty Max, I first tried using rooms but the room owner not receiving all the user callbacks makes things somewhat complicated... Hope to see the missing callbacks being added to the library at some point.


I know that there is much to do.
I have to excuse my lack of updates recently. I am pretty busy preparing a scientific paper for a student symposium.
_________________
GBAMP Multiboot

#144815 - yellowstar - Wed Nov 07, 2007 10:17 pm

That works pretty good, melw.(minus the minor problems)
Much better than mine.
I'll have a look at the source,
and see if I can figure something out.

I'm using a timer.(For detecting when opponet quit,
and for debugging.)
(I was using 4, but I have changed it so
only one is used.)(They all used to have the same settings)(minus
the Timer IRQ Handler)

I'm having more problems.
The client isn't detecting any scoring messages at all.
Could Timers have been creating problems?
(This problem might be due to a bug in my code)

#144819 - melw - Wed Nov 07, 2007 10:41 pm

Mighty Max wrote:
I know that there is much to do.
I have to excuse my lack of updates recently. I am pretty busy preparing a scientific paper for a student symposium.

No worries. Complete room functionality is going to be good to have, but in the end LOBBY_SendToUser() is all we need...

yellowstar wrote:
I'm having more problems. The client isn't detecting any scoring messages at all.

Feel free to use the source I posted and modify it in any way you wish to. I chose to send scores at the same time with ball update messages (as when ball goes out of the borders, scoring is updated too). Don't see how one kind of messages wouldn't go through and then all the others would...

IRQ timers aren't necessarily needed for a game like this. Incrementing a frame counter in VBlank() gives you a running timer that is updated 60 times in a second. In other words, if timers are giving you too much headache - just don't use 'em. :)

#144825 - yellowstar - Thu Nov 08, 2007 12:31 am

I tried to figure out that source, but...(it's hard
to understand (and ect) in its current state)

As for timers,
they aren't used for game-specific things.
They are only used for debugging,
and detecting when the opponet quit.

I tried disabling timers,
but that didn't change anything.(that is, the scoring messages)

Maybe those room problems
are what's causing my room problems.

EDIT:
This might not help,
but here's this game in it's current state.
(Don't worry, this is the correct archive)

EDIT2:
To compile this,
you'll need to download my
lib.(it makes using the wireless lib easier,
among other things.)

(The debugging has been removed.)(at least at the time of writing this)
(This means you can startup the game any way you want.)
(Also, all most everything seems to be in sync,
except scores.)
(This means you should be able to play it normally.)
(That is, play and watch the game on your own DS.)


Last edited by yellowstar on Thu Nov 15, 2007 2:31 am; edited 1 time in total

#144854 - melw - Thu Nov 08, 2007 10:42 am

yellowstar wrote:
I tried to figure out that source, but...(it's hard
to understand (and ect) in its current state)

Heh.. and I tried to keep it short and simple. Not too many comments, though. Exchanging the user data during the game is done with two messages MESSAGE_GAME_UPDATE_BALL/BAT. Only server has control over the ball, but client also sends bat update messages. Bat accurancy is shifted by 2 (0...192*4) and the ball position values are shifted by 11 (0...256*2048 x 0...192*2048). As we're passing only unsigned chars in the lobby messages, these values are split into 2 and 3 char chunks while transferring. First char of the message is always the identifier (MESSAGE_GAME_...). These update messages are sent only when something happens (ball hits a wall, bat or goes out of the field, bat starts / stops movement).

Debugging tips: if you're not searching for crash bugs, printing on the sub screen has its advantages. What comes to your scoring messages problem - obviously you have a bug somewhere, nothing wrong with the lobby library.

#145295 - yellowstar - Tue Nov 13, 2007 10:58 pm

I think I found the solution.

For handling messages,
it does not handle them in the stream callback.(that
is, processing them, updating scores, bat pos, ect.)
(Unlike melw's code)
Instead, they are handled in vblank.(not
the interrupt, in the infinite while loop.)

Since that is not in the callback,
messages can be missed, and disorted.
Once a certain message is detected,
the callback could trigger before
it finishes processing,
and thus disorting the message.(the message would
be actually the new, recieved message)

In theory,
once I fix this,
it should work.

#145308 - Mighty Max - Wed Nov 14, 2007 12:03 am

Yes, this is indeed very likely a major problem.
The data passed to a callback is only valid within the callback.

Maybe i should add a more asynchonous method for retrieving data from a stream, with enlisting messages for which no callback is defined, with proper methods to check for and get these messages....
_________________
GBAMP Multiboot

#145330 - yellowstar - Wed Nov 14, 2007 4:13 am

I fixed it.

But, I am still having problems.

The host's score on the client is correct.
But, the client's score on the client is wrong.

I'm trying to send sync messages(host)
when the ball
hits a wall.

These messages contain the score of the host and client.

I'm going to update the download, tomorrow.


I have gotten my NiFi EEPROM
app to work.(the reading and backup part)
I just need to compare the output
with the actual EEPROM to confirm the output is correct.

There is a bug in it that could
cause crashes and corrupt output
with EEPROM sizes larger than 512.(bytes)
I'm still trying to figure out
how to fix it.(I know what's the problem)

#145414 - yellowstar - Thu Nov 15, 2007 2:37 am

I have updated the download.(goto
my download post for that.)
(On the previous page, at the bottom of that page.)

Here's what's happening with the client's scores:
It seems to be switching between 0 and 1.

It is never the correct score.


My NiFi EEPROM app
output isn't the same as another app I
compared.(the example in the current nds examples)

Later,
I'm going to test it with other EEPROM tools.

EDIT:
Another thing:
When I disable sending sync messages,
the scoring on the client is always zero.
(This must mean there's a problem with
the scoring messages.)


And another thing:
Recently I accidently
deleted the code
for rooms.(to update with my small lib.)
I'll need to rewrite this code.(this time
in my lib.)
Maybe I'll get it working once I get to rewriting it.

#145473 - yellowstar - Fri Nov 16, 2007 3:30 am

I tried adding code
to disable and enable
interrupts at the start and end
of the send message functions,
but that didn't do anything.


I've been having troubles
with one DS crashing.

This problem is caused by FAT,
but I haven't figured out how to fix it.

#145553 - yellowstar - Sat Nov 17, 2007 8:21 pm

I have gotten the client's scores on the client
to work better.

Now,
they switch between 0 and the real score.
(I still haven't gotten FAT working again.)

#145661 - yellowstar - Tue Nov 20, 2007 3:52 am

I'm having strange problems with all my wireless programs.
(Pong and NiFi EEPROM)

The host and client won't detect the other.
This makes it impossible to do anything.
(That means no gameplay, and no EEP transfers.)

This must be caused by some kind of
bug in my small lib.

I have moved all init
code to the lib.
Also,
I have moved all the cpp
files to the source directory.(they
were previously in the include dir for including.)

One of the above is probably causing the problem.
(It's more likely it's the second thing.)

#145725 - yellowstar - Wed Nov 21, 2007 12:44 am

I have solved it.

The new init wireless function
wasn't being called.(IPC_SetChannelCallback)

#146039 - yellowstar - Tue Nov 27, 2007 10:49 pm

I have decided to give up on this.

Even if I did get it working,
it would probably be hacky still.
(And a hacky pong game,
for the first every pong game,
would be very bad.)
(And tutorials based on it would be bad too.)

I might keep working on this, however.


I'm having problems with rooms, again.

It's crashing at a differen't point this time.
But, one of the systems seems to still
be crashing.

I might go back
to working on my SFB game soon, again.

#147588 - yellowstar - Mon Dec 24, 2007 1:01 am

It's nearly done!
But, there's some minor sync issues,(bat positions)
and a major crash bug.(Mysterious, I played it with one person,
but something happened and problems started with the next person)

I was planning on getting it done and released by Xmas,
but... I was going to release it today, but unless this problem is solved
TODAY, it can't be solved and released before then.
(I can't get much of anything done Xmas Eve)

It's the Red Screen(s) of Death.
addr2line doesn't help.
1st pc = FFFF7FFC 2nd = FFFF8004
(1st is top-left value, other is bottom-right one with the other regs)

It worked pretty good with the first test. Good enough to be released if it weren't for this problem.

#147625 - yellowstar - Mon Dec 24, 2007 10:23 pm

I solved it.

I had it going into an infinite loop, and that caused the Red Screens of Death.

You can download it here.(src+bin)

The ball on the client side is out sync REALLY bad. But, it's still playable.

I wanted to add realistic 360 degree movement and collisions, but I'll try doing that later.
(I'll use melw's code for that. I guess you wouldn't mind melw?)

I could use some help with getting it into sync better.
(melw?)

#147702 - melw - Wed Dec 26, 2007 3:58 pm

yellowstar wrote:
I wanted to add realistic 360 degree movement and collisions, but I'll try doing that later.
(I'll use melw's code for that. I guess you wouldn't mind melw?)

I could use some help with getting it into sync better.
(melw?)

By all means. Even if the pong example in lobby lib svn isn't really properly finished either - the "realistic" ball movement is in fact rand(). One should rather calculate the ball angle depending on where the ball collides with the bat.

The sync messages are described few posts up, and it's essentially still the same (can't remember if there's any updates since 1? months ago).

#147780 - yellowstar - Thu Dec 27, 2007 9:40 pm

melw wrote:
yellowstar wrote:
I wanted to add realistic 360 degree movement and collisions, but I'll try doing that later.
(I'll use melw's code for that. I guess you wouldn't mind melw?)

I could use some help with getting it into sync better.
(melw?)

One should rather calculate the ball angle depending on where the ball collides with the bat.

That's what I wanted to do, but the math for that is complicated. How would do such a equation?(I have a PC tutorial with the PC equation)