Archives for posts with tag: realtime

A long time ago I toyed with the idea of making an entire game by myself. Being a driving game, I spent a long time with the basics stuff like vehicle physics to make sure the driving part is stable, bug-free, and most importantly, fun.

I never finished it. But ever since I posted the above video, I have been getting a lot of inquiries as to how I did the vehicle physics system in Blender. So here is a quick guide followed by the sample file.

The key to stable driving dynamics is to use the built-in PhysicsConstraints module within Blender’s game engine. PhysicsConstraints is a python wrapper for the Bullet physics engine. No any homemade setup I’ve seen is as good as what’s already provided by Bullet Physics. So we’ll use that.  Because there isn’t a graphical interface for setting up the vehicle physics yet in Blender, we need to write a few lines of Python script.  The key component is the car body object, which is linked to the 4 wheels through a logic brick connection so that the script would recognize the linked objects as wheels. (As you can see, all the actual driving logic is all happening on the car body, the wheels have no real logic brick attached).

The entire setup is a bit complex, since there is a mix of logic brick and python. Take a look at the sample file if you are lost.  When one runs the game, the following happens:

0. World is initialized, but we don’t really care about that here.

1. The car body is initalized, scripts.carInit() is ran. In this script, it initializes the car as a “vehicle constraint”, aka constraint type11, and stores it as a Python object called vehicle.  The same script then looks for the 4 wheel by access a gamelogic actuator with specific names (in this case, wheel1, wheel3, etc), then the script attaches the wheels to the car body using the settings specified in the script. Variables such as RollInfluence, SuspensionStiffness, and TyreFriction can all be set on a per-tire basis once the vehicle object is created. The job of carInit() is now done.  Our car body is now considered to be a vehicle by the Blender game engine, and it will behave like one.

2. Every frame, scripts.carHandler() is ran. This script does the actual moving of the car, it applies engine force and steering to the vehicle object. But this script gets the user input (keyboard sensor inputs) from another source. (See #3 below)   Vehicle objects have methods such as applyBreaking(), applyEngineForce(), getWheelRotation(), getNumWheels, which you can all call.

3. Every time a key is pressed, script.keyHandler() is ran. It figures out which key is pressed and set the intermediate variable so that #2 (i.e. scripts.carHandler) would know how much throttle to apply, where to steer, etc.  This script is separated from scripts.carHandler() not because of technical limitations, but by design so that it’s easier to manage the code.

That’s all there is to it.  If the script layout is a bit confusing, it’s because it is.  I originally intended it to be a bigger project, thus everything is separated into nice neat functions.  Again, you can DOWNLOAD the whole setup for Blender 2.5 from here.

Controls:
Arrow Keys to move the car
Space bar for handbrake
R to reset car if it flips over
number row 1,2,3,4,5 to change camera

Hope that helped.

I had been lucky enough to be a part of a very cool project taking place at the Fisheries Centre at the University of British Columbia.  In a nut shell, we are trying to create a 3D underwater visualization using the Blender Game Engine to display scientific data in a more pleasing way.  Basically translating a stream of mind-numbing data:

into something prettier:

The visualization data is coming from EwE6, a well-respected ecosystem modeling software.  Blender uses inputs such as biomass, water turbidity and light level to create a realtime visualization that allows the user to ‘swim’ around in the ocean, watch the schools of fish interact, and see their population change over time.

To accomplish all this, the project consists of 3 layers:

The server core does all the heavy computation while the visualization layer does all the graphics, AI, as well as user interaction.  To facilitate the communication across these two separate processes, a third layer (called the GameClient) is created, providing the bridge.

Being a Blender artist, my main focus is on the visualization layer: the Blender Game Engine.  In the following few posts, I will outline the process in creating this application, and describe some of the issues we faced.  Please leave a comment if you are interested, it will motivate me to write more :)

A while ago, I posted a simple demo I made in the Blender game engine that let’s 2 player interact with each other over the internet, all it is required is a really simple networking script and the IP address of the two players.  Here is as youtube video of it in action, mouse-over the video to see some caption text.

The laptop on the left is physically separated from the desktop to the right, linked only by a wireless internet connection. And as you can see, input made to the desktop computer is sent across the network to the laptop, in realtime.

And here is the script, I’ll try to explain everything as best I can:

# Simple Python UDP networking demo Created by Mike Pan
# Todo: auto-self IP detection would be nice

# the following line loads the game module used by Python
# to access the Blender Game Engine API, and assigns it the alias G
import GameLogic as G
# load the network socket python module, we'll need it later
import socket

# define own IP address, and stores it as a property under GameLogic
# essentially making it accessible as a global variable
G.ownIP = "xxx.xxx.xxx.xxx"
# define peer IP address, stores it as a property under GameLogic
# again, essentially making it accessible as a global variable
G.peerIP = "xxx.xxx.xxx.xxx"
# define the port number (arbitrary), and the socket buffer size
# (4096 is a good starting point)
G.port = 4000
G.buffer = 4096

# create an IPV4 address with the pre-defined IP and the port number
addr = (G.peerIP, G.port)

# We'll add this line to all our communication, so when debugging,
# we won't get confused as to who send the packets.
signature = "Sent from " + G.ownIP

def init():
	# create an UDP socket for **sending** datagram
	G.sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	# time out is 10ms, pretty short for realworld application,
	#but enough for debugging over local network
	G.sender.settimeout(0.01)
	# this is important! by making this socket object a
	# non-blocking operation, all network stuff is run on
	# a separate thread, thus any network delay will not
	# cause the game to slow down
	G.sender.setblocking(0)

	# creates UDP socket for **receiving** datagram
	G.listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	# same as above, time out is 10ms
	G.listener.settimeout(0.01)
	# same as above, we also need to make sure network operations
	# will not slow down the main application
	G.listener.setblocking(0)

	# Win32 needs the socket binded:
	try:
	 G.listener.bind((G.ownIP, G.port))
	except:
	 print "Binding Listener failed"

def comm():
	# get the object that is attached to this script
	own = G.getCurrentController().owner

 	# receive from peer
	try:
		data, port = G.listener.recvfrom(G.buffer)
		# data contains all the data that came through,
		# it's a string, and we can do whatever we want
		# like print it out
		print data.split(',')
	# if the receiving fails, print something to notify the user
	except:
		print "Receive failed"

	# send to peer
	# generate data to be sent here,
	# send the position data across the network:
	string = str(own.worldPosition)+ ',' + signature

	# going to try to send the data
	try:
		G.sender.sendto(string, addr)
		# if sending fails, notify with error message
	except:
		print "Send failed"

That’s it! To use this script, we simply need to call init() once at the start of the game, and then comm() everytime you wish to send/receive some data (perhaps every 1/30th of a second). As mentioned, here is no ‘server’ involved, the two peers connect direction to each other via a UDP socket. All the user has to do is specify the two IP addresses.

It’s still very early, but here is the first video capture of the game I am working on at the moment: