Welcome! Log In Create A New Profile

Advanced

Making a Head-to-Head Online Game

Posted by Arikado 
Making a Head-to-Head Online Game
January 07, 2009 12:36AM
I just recieved a wireless router today (for my birthday, incase anyone cares). I'm enjoying playing brawl and mario kart online. Then it occured to me. We dont have any homebrew head-to-head or player vs player games. Not one to complain I quickly wrote up (in less than an hour to be exact) an extremely simple game I'm tentatively calling BattlePong.

An HBC compatible version of it can be downloaded here.

The source can be downloaded here.

As you'll see from using it, I'd like to incorporate a two player online mode into the game. My question isn't how, but instead, is it possible? Are we far enough with the network functions in libogc that this can actually be acieved? If so, can anyone give me any pointers about network programming (I've never done any before)? Furthermore, is anyone willing to help me achieve my goal?

Thanks in advance to any and all repliers,
Arikado

BTW I'm uploading the source code and publicly releasing the link tomorrow after I clean up the code a little bit. I'd also appreciate it if everyone does not post BattlePong on Wiibrew or anywhere else on the internet for that matter.



Edited 1 time(s). Last edit at 01/08/2009 06:51PM by Arikado.
Re: Making a Head-to-Head Online Game
January 07, 2009 12:39AM
Heh, sounds good. I'd like to see this idea as well. I forgot who it was, but somebody gave out a little demo application on #wiidev that a bunch of people connected to his computer, and you were Mario, and you could run around and jump, while you saw everyone else doing whatever they were doing, except they were Luigi.

You might try asking around on there to see who wrote it, and ask them for some help.
Definitely seems possible though, especially for a game as simple as Pong.
Re: Making a Head-to-Head Online Game
January 07, 2009 12:45AM
Thats exactly what I thought. Unfortunately, I can never get on #wiidev. botty kicks me off for not using a compatible IRC client. And right now, I cant even get on efnet ever since I installed the new router. Supposedly, I have a "black proxy" or an incompatible IP address or something like that. Thanks for the encouraging response though.
Re: Making a Head-to-Head Online Game
January 07, 2009 12:48AM
Hmm, that sucks. Well, by incompatible client, it usually means you are using a Web IRC Client.
Try using ChatZilla, I use that when I can't use a real client.
Also, regarding the EFnet problem, maybe try using a different server? irc.Prison.NET has always served me well.
Re: Making a Head-to-Head Online Game
January 07, 2009 12:52AM
We're getting a little too offtopic but thanks for your suggestions, I'll see what I can do. In the meantime, if you see anyone on the irc channels that you think may be able to help me, please direct them to this topic.
Re: Making a Head-to-Head Online Game
January 07, 2009 12:53AM
Haha, will do, although I bet everyone on the channel is seeing this thread, because LogMii tells the channel about every post on the Forums in the coding section =P
Re: Making a Head-to-Head Online Game
January 07, 2009 08:41AM
I've not checked the libogc for network functions, but if it has "Listen", "Connect", "Disconnect", "Send", and "Receive" functions (I'm sure it will have), you have everything you need.

Easy way of doing a 2 player game is peer-to-peer.

Player 1 starts up the game, and picks a "Start as Server" mode. (S)he'll need to know his/her internet IP address to send to their friend.
The server mode Listens on a port number (Can be almost any, generally pick above 1024, I think). Make sure your router forwards traffic from your port on your router to your Wii

Player 2 will pick "Start as Client" mode, and will need to enter Player 1's IP address, then you'll need to called Connect with your port number and IP address

When an incoming request comes in at Player 1's side, you accept it (which creates the connection), and then you use Send and Receive to send any data between clients (this can be anything you want, you generally "handshake" first, to confirm you're both running the same version etc. first (although it's not necessary))
Re: Making a Head-to-Head Online Game
January 08, 2009 01:57AM
Wow sounds cool. I'll have to check it out. I'm working on a 2D karate fighting game right now and have been thinking about doing a multiplayer version also. I'm a few weeks out from a release as the sprites are a big time consumer :)

I was thinking of setting up a master server to handle any servers that are running then you'd be able to browse from the game to join. But I guess we'll see how it goes.



Edited 1 time(s). Last edit at 01/08/2009 01:58AM by scanff.
Re: Making a Head-to-Head Online Game
January 08, 2009 02:49AM
Glad to know it's possible. I really wanted to implement online capabilities in SEAMS, but that probably won't happen for a while, just so I can get out a working version as fast as possible.
Re: Making a Head-to-Head Online Game
January 08, 2009 10:10AM
I was thinking about adding it to Wiicross but I didn't because 1) don't have inet at home, 2) don't have time to code, but the idea of making a VS battle mode is interesting (like picross on ds).
Re: Making a Head-to-Head Online Game
January 08, 2009 06:26PM
From network.h:

u32 inet_addr(const char *cp);
s8 inet_aton(const char *cp, struct in_addr *addr);
char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */

s32 if_config( char *local_ip, char *netmask, char *gateway,boolean use_dhcp);
s32 if_configex(struct in_addr *local_ip,struct in_addr *netmask,struct in_addr *gateway,boolean use_dhcp);

s32 net_init();
s32 net_socket(u32 domain,u32 type,u32 protocol);
s32 net_bind(s32 s,struct sockaddr *name,socklen_t namelen);
s32 net_listen(s32 s,u32 backlog);
s32 net_accept(s32 s,struct sockaddr *addr,socklen_t *addrlen);
s32 net_connect(s32 s,struct sockaddr *,socklen_t);
s32 net_write(s32 s,const void *data,s32 size);
s32 net_send(s32 s,const void *data,s32 size,u32 flags);
s32 net_sendto(s32 s,const void *data,s32 len,u32 flags,struct sockaddr *to,socklen_t tolen);
s32 net_recv(s32 s,void *mem,s32 len,u32 flags);
s32 net_recvfrom(s32 s,void *mem,s32 len,u32 flags,struct sockaddr *from,socklen_t *fromlen);
s32 net_read(s32 s,void *mem,s32 len);
s32 net_close(s32 s);
s32 net_select(s32 maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,struct timeval *timeout);
s32 net_setsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen);
s32 net_ioctl(s32 s, u32 cmd, void *argp);
s32 net_fcntl(s32 s, u32 cmd, u32 flags);
s32 net_shutdown(s32 s, u32 how);

struct hostent * net_gethostbyname(char *addrString);

Looks like we've got all the necesarry functions (and more).
Re: Making a Head-to-Head Online Game
January 08, 2009 06:49PM
Okay, I've updated battlepong (bug fix) so it now has to be downloaded here. I've just uploaded the source. It is available here. I've also updated the first post with the links.
Re: Making a Head-to-Head Online Game
January 08, 2009 07:59PM
Hi Arikado,

I just downloaded your source but cannot see that the network stuff is in there. There are a few functions that are commented out that look like they are network related.
Re: Making a Head-to-Head Online Game
January 08, 2009 08:40PM
Yeah, theres no network code at all in there. Just some comments showing how we only need to send Y coordinates to make it work online. Hopfully someone will bring network into it.
Re: Making a Head-to-Head Online Game
January 09, 2009 02:27AM
Hey Arikado,

You may want to look at the source for pong2 by wplaat. It has tcp connections in there. (http://members.tele2.nl/wplaat/wiibrew.html)

Most of the work looks like it's been done in http.c. Obviously it's geared towards the http protocol but the connect, read and write should be the same if your using a TCP connection for a game. You only then need to write the server which it pretty simple with TCP. Basically you need a listen thread that accepts connections then saves the connection socket so you can communicate with the client.
Re: Making a Head-to-Head Online Game
January 09, 2009 03:09AM
Pong2 uses a library wplaat wrote. For the moment Im sticking with libogc. The rest of your post was very helpful, thank you.
Re: Making a Head-to-Head Online Game
January 09, 2009 03:23AM
In the libogc examples there a network example. It's under "examples/gamecube/devices/network/".

Even though its for gamecube it should work on the wii, I really don't see why it wouldn't.

*edit: btw Happy belated Birthday :p



Edited 1 time(s). Last edit at 01/09/2009 03:24AM by Matando.
Re: Making a Head-to-Head Online Game
January 09, 2009 06:56AM
Quote
Matando
In the libogc examples there a network example. It's under "examples/gamecube/devices/network/".

Even though its for gamecube it should work on the wii, I really don't see why it wouldn't.

*edit: btw Happy belated Birthday :p

Genius! I never think to look at the gamecube code. A few edits in the makefile and it works like a charm. Then just open up a browser and browse to the Wii's IP and bingo the Wii is a simple web server.

Just for reference here's the edited makefile I used for Wii.

#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC")
endif

include $(DEVKITPPC)/wii_rules

#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET		:=	$(notdir $(CURDIR))
BUILD		:=	build
SOURCES		:=	source
DATA		:=	data  
INCLUDES	:=

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------

CFLAGS	= -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS	=	$(CFLAGS)

LDFLAGS	=	-g $(MACHDEP) -Wl,-Map,$(notdir $@).map

#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS	:=	-ldb -logc -lm

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS	:=

#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------

export OUTPUT	:=	$(CURDIR)/$(TARGET)

export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
					$(foreach dir,$(DATA),$(CURDIR)/$(dir))

export DEPSDIR	:=	$(CURDIR)/$(BUILD)

#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES	:=	$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
	export LD	:=	$(CC)
else
	export LD	:=	$(CXX)
endif

export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
					$(sFILES:.s=.o) $(SFILES:.S=.o)

#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
					$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
					-I$(CURDIR)/$(BUILD) \
					-I$(LIBOGC_INC)

#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS	:=	$(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
					-L$(LIBOGC_LIB)

export OUTPUT	:=	$(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean

#---------------------------------------------------------------------------------
$(BUILD):
	@[ -d $@ ] || mkdir -p $@
	@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
clean:
	@echo clean ...
	@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol

#---------------------------------------------------------------------------------
else

DEPENDS	:=	$(OFILES:.o=.d)

#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)

#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o	:	%.jpg
#---------------------------------------------------------------------------------
	@echo $(notdir $<)
	$(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

Re: Making a Head-to-Head Online Game
January 09, 2009 09:00AM
Woah, thanks. Coincidentally, I'm also trying to make a networked program, although I'm trying to make an RSS reader first and then possibly progress to a web browser. I haven't done networking in C before but I did write a multiplayer networked game in java for a class, and am working on another now. I can help with the overall concepts at least, and possibly with code later but I'm still learning myself.

For a game, you're going to want to use a client/server model, and I guess the difficulty in doing this on a console is deciding whether you want the server to run on a computer somewhere or on one of the Wiis playing the game. Ideally it would run on one of the Wiis but then you run in to the problem of finding other players. I suggest for the first version just having people enter the other person's IP address to keep things simple, and then later you can write a game listing portion that uses some other server to list all the current servers hosting the game.

Note that the client and server aren't necessarily separate programs, and probably are just separate threads on the same Wii. I don't know anything about threading in C so I can't help with that. However, this is basically what each part needs to do:

The server thread will coordinate the clients and pass data between them. One thread will listen for new connections from clients by opening a server socket on a certain port, and when clients connect and do the proper authentication or whatever you want to have, spawn a new thread that will specifically handle communication between the server and that specific client. Each child thread will wait for data from its client, and then when it receives new data it should forward this to all the other clients. Your implementation could vary, but probably you will have some sort of list of new messages that need to be forwarded to all clients, and then the threads will process this information and send it accordingly.

On the client side, you will have two threads. One will be the counterpart to the child threads from the server; it will coordinate the connection information and send/receive data to and from the server. The other thread will run your general game logic and cooperate with the data thread to communicate with the server.

Hopefully, this should be enough information to get you started. Unfortunately, it seems like with C there isn't as much of a standardized set of tutorials as there are with Java but if you want you could check out the Sun Java networking tutorial and glean some higher level information from it; the general structure of your program will probably be similar although you will have to deal with more implementation specific details instead of having nice classes that just open a socket on the specified IP address, but they should be good for ideas.

I also recommend you try searching for the names of the functions in network.h, although you're probably doing that already anyway. It's helping me a lot since network.h itself isn't very well documented. I also happened upon this network programming tutorial for C, but it lists some stuff that it mentions is outdated but libogc still uses. Particularly the stuff about IPv6 and certain functions relating to it, but you can look in network.h to see which functions you have access to.



Edited 1 time(s). Last edit at 01/09/2009 09:04AM by iofthestorm.
Re: Making a Head-to-Head Online Game
January 09, 2009 09:23AM
Cool stuff!

I'm actually getting inspired by the simple gc code Matando pointed us to. I'm currently writing a multithreaded server right now but it's getting late ... yawn. So I'll continue tomorrow and hopefully have something working and posted in the next few days.

I've actually done a few client servers in the past for linux and windows so it's a good refresher for me.
Sorry, only registered users may post in this forum.

Click here to login