<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>fiber-optic megawatts</title>
	<atom:link href="http://qiroka.com/dev/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://qiroka.com/dev/blog</link>
	<description>video game development</description>
	<pubDate>Sat, 03 Jul 2010 17:00:33 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Editing Outlook Calendars With Ruby</title>
		<link>http://qiroka.com/dev/blog/?p=112</link>
		<comments>http://qiroka.com/dev/blog/?p=112#comments</comments>
		<pubDate>Sat, 03 Jul 2010 16:50:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://qiroka.com/dev/blog/?p=112</guid>
		<description><![CDATA[
I admit it.  I&#8217;m a pretty lazy guy.  I don&#8217;t have much patience for mind-numbingly repetitive tasks.  They bring me down.  Editing my Outlook calendar every day is simply a waste of time in my opinion.  I figured that there must be a way to automatically create appointments  through [...]]]></description>
			<content:encoded><![CDATA[<p><img alt="" src="http://qiroka.com/blogs/dev/images/laziness.png" title="laziness" class="alignnone" width="440" height="176" /></p>
<p>I admit it.  I&#8217;m a pretty lazy guy.  I don&#8217;t have much patience for mind-numbingly repetitive tasks.  They bring me down.  Editing my Outlook calendar every day is simply a waste of time in my opinion.  I figured that there must be a way to automatically create appointments  through some kind of script.  Then I wondered if Ruby could help.</p>
<p>After doing some quick research, I found out that it&#8217;s actually quite easy to connect Ruby and Outlook.  This is done through Microsoft&#8217;s Object Linking and Embedding (<a href="http://en.wikipedia.org/wiki/Object_Linking_and_Embedding">OLE</a>) protocol.  I wasn&#8217;t able to find a definitive tutorial for Ruby and OLE, but there is enough information scattered about the internet to get a simple script up and running.</p>
<p><span id="more-112"></span></p>
<p>Modifying an Outlook calendar from Ruby basically boils down to knowing how to do three things: 1) Opening a context to Outlook, 2) Connecting to the &#8220;Calendar&#8221; (as opposed to the Mailbox, Contacts, etc.), and 3) Creating/Listing appointments.  I learned how to do all of this from the following sources:</p>
<ol>
<li><a href="http://downloads.sybase.com/codexchange/powerbuilder/404/PowerBuilder_-_Controlling_the_Outlook_session_using_OLE.htm">Controlling the Outlook session using OLE</a></li>
<li><a href="http://www.artima.com/forums/flat.jsp?forum=123&#038;thread=111926">Outlook Appointments with Ruby</a></li>
<li><a href="http://rubyonwindows.blogspot.com/2007/07/automating-outlook-with-ruby-sending.html">Automating Outlook with Ruby: Sending Email</a></li>
<li><a href="http://www.ruby-doc.org/stdlib/libdoc/win32ole/rdoc/index.html">win32ole Ruby Standard Library Documentation</a></li>
</ol>
<p>Those links provided enough information for me to write a script that connects to my calendar and prints out all of my existing appointments.  It&#8217;s not much, but as a proof-of-concept it&#8217;s not bad.</p>
<p>And here&#8217;s the code.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># 28 June 2010, Phillip Weisberg &lt;fettuccini@qiroka.com&gt;</span>
<span style="color:#008000; font-style:italic;"># License: Creative Commons 3.0 Attribution 3.0 Unported</span>
<span style="color:#008000; font-style:italic;"># Purpose: Demonstrates how to read/add items in a Microsoft Outlook calendar</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># References:</span>
<span style="color:#008000; font-style:italic;">#   Controlling the Outlook session using OLE: http://downloads.sybase.com/codexchange/powerbuilder/404/PowerBuilder_-_Controlling_the_Outlook_session_using_OLE.htm</span>
<span style="color:#008000; font-style:italic;">#   Outlook Appointments with Ruby: http://www.artima.com/forums/flat.jsp?forum=123&amp;amp;thread=111926</span>
<span style="color:#008000; font-style:italic;">#   Automating Outlook with Ruby: Sending Email: http://rubyonwindows.blogspot.com/2007/07/automating-outlook-with-ruby-sending.html</span>
<span style="color:#008000; font-style:italic;">#   win32ole Ruby Standard Library Documentation: http://www.ruby-doc.org/stdlib/libdoc/win32ole/rdoc/index.html</span>
<span style="color:#008000; font-style:italic;">#</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
<span style="color:#008000; font-style:italic;"># Requires</span>
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'win32ole'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'date'</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
<span style="color:#008000; font-style:italic;"># Struct Definitions</span>
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
&nbsp;
<span style="color:#CC00FF; font-weight:bold;">Struct</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">&quot;AppointmentInfo&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:Subject</span>, <span style="color:#ff3333; font-weight:bold;">:Body</span>, <span style="color:#ff3333; font-weight:bold;">:Start</span>, <span style="color:#ff3333; font-weight:bold;">:End</span>, <span style="color:#ff3333; font-weight:bold;">:ReminderSet</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
<span style="color:#008000; font-style:italic;"># Instance Variables</span>
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
&nbsp;
<span style="color:#0066ff; font-weight:bold;">@outlookApplication</span> = WIN32OLE.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">'Outlook.Application'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
<span style="color:#008000; font-style:italic;"># Methods</span>
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Creates a new appointment in Outlook ---</span>
<span style="color:#9966CC; font-weight:bold;">def</span> CreateOutlookAppointment<span style="color:#006600; font-weight:bold;">&#40;</span> appointmentInfo, categories <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># Verify that the appointment ends after it starts (Note that the data of an all-day event appears to end before it starts)</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> appointmentInfo.<span style="color:#9966CC; font-weight:bold;">End</span> <span style="color:#006600; font-weight:bold;">&lt;</span>= appointmentInfo.<span style="color:#9900CC;">Start</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;[createAppointment] Warning: Appointment creation aborted due to end date before start date.&quot;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
   <span style="color:#008000; font-style:italic;"># Create the Outlook application item</span>
   appointment			= <span style="color:#0066ff; font-weight:bold;">@outlookApplication</span>.<span style="color:#9900CC;">CreateItem</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span>		<span style="color:#008000; font-style:italic;"># 1 = Creates an appointment</span>
   appointment.<span style="color:#9900CC;">Subject</span>		= appointmentInfo.<span style="color:#9900CC;">Subject</span>
   appointment.<span style="color:#9900CC;">Body</span>		= appointmentInfo.<span style="color:#9900CC;">Body</span>
   appointment.<span style="color:#9900CC;">ReminderSet</span>	= appointmentInfo.<span style="color:#9900CC;">ReminderSet</span>
   appointment.<span style="color:#9900CC;">Start</span>		= appointmentInfo.<span style="color:#9900CC;">Start</span>
   appointment.<span style="color:#9966CC; font-weight:bold;">End</span>		= appointmentInfo.<span style="color:#9966CC; font-weight:bold;">End</span>
   appointment.<span style="color:#9900CC;">Categories</span>	= categories
&nbsp;
   appointment.<span style="color:#9900CC;">Save</span>
   <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Created Appointment: [#{appointment.Subject}] at #{appointment.Start}&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Finds a listing of all appointments on the specified date from a list of existing appointments ---</span>
<span style="color:#9966CC; font-weight:bold;">def</span> FindExistingAppointmentsForDate<span style="color:#006600; font-weight:bold;">&#40;</span> existingAppointments, dateStart <span style="color:#006600; font-weight:bold;">&#41;</span>
  appointmentsForDate = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
  existingAppointments.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>currAppointment<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> currAppointment.<span style="color:#9900CC;">Start</span>.<span style="color:#9900CC;">year</span> == dateStart.<span style="color:#9900CC;">year</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#006600; font-weight:bold;">&#40;</span> currAppointment.<span style="color:#9900CC;">Start</span>.<span style="color:#9900CC;">month</span> == dateStart.<span style="color:#9900CC;">month</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#006600; font-weight:bold;">&#40;</span> currAppointment.<span style="color:#9900CC;">Start</span>.<span style="color:#9900CC;">day</span> == dateStart.<span style="color:#9900CC;">day</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
	    appointmentsForDate.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span> currAppointment <span style="color:#006600; font-weight:bold;">&#41;</span>
	  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  <span style="color:#0000FF; font-weight:bold;">return</span> appointmentsForDate
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Loads all of the existing calendar appointments into the array @existingAppointments ---</span>
<span style="color:#008000; font-style:italic;"># --- TODO: Load recurrences as appointments (currently, they are ignored) ---</span>
<span style="color:#9966CC; font-weight:bold;">def</span> LoadExistingAppointments
  namespace = <span style="color:#0066ff; font-weight:bold;">@outlookApplication</span>.<span style="color:#9900CC;">GetNamespace</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">&quot;MAPI&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  ole_folder = namespace.<span style="color:#9900CC;">GetDefaultFolder</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006666;">9</span> <span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># 9 = Calendar</span>
  numItems = ole_folder.<span style="color:#9900CC;">Items</span>.<span style="color:#9900CC;">Count</span>
&nbsp;
  existingAppointments = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> idx <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006666;">1</span> .. <span style="color:#9900CC;">numItems</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    currItem = ole_folder.<span style="color:#9900CC;">Items</span>.<span style="color:#9900CC;">Item</span><span style="color:#006600; font-weight:bold;">&#40;</span> idx <span style="color:#006600; font-weight:bold;">&#41;</span>
	  dateStart = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span> currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>,	currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9900CC;">Start</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	  dateEnd = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span> currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>,	currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, currItem.<span style="color:#9966CC; font-weight:bold;">End</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;:&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	  tempAppointment = <span style="color:#6666ff; font-weight:bold;">Struct::AppointmentInfo</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> currItem.<span style="color:#9900CC;">Subject</span>, <span style="color:#996600;">&quot;&quot;</span>, dateStart, dateEnd, <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;
	  existingAppointments.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span> tempAppointment <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#0000FF; font-weight:bold;">return</span> existingAppointments
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
<span style="color:#008000; font-style:italic;"># Main Program</span>
<span style="color:#008000; font-style:italic;">#------------------------------------------------------------------------------</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Load all existing appointments and print the contents ---</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;-----[All Existing Appointments]----------------------------------------&quot;</span>
existingAppointments = LoadExistingAppointments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
existingAppointments.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>existingAppointment<span style="color:#006600; font-weight:bold;">|</span>
   <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Existing Appointment: [#{existingAppointment.Subject}] at: #{existingAppointment.Start}&quot;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;------------------------------------------------------------------------<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Find all appointments for a specific day and print the contents ---</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;----[Existing Appointments Today]---------------------------------------&quot;</span>
dateToday           = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
appointmentsForDate = FindExistingAppointmentsForDate<span style="color:#006600; font-weight:bold;">&#40;</span> existingAppointments, dateToday <span style="color:#006600; font-weight:bold;">&#41;</span>
appointmentsForDate.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>appointmentForDate<span style="color:#006600; font-weight:bold;">|</span>
   <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Existing Appointment: [#{appointmentForDate.Subject}] at: #{appointmentForDate.Start}&quot;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;------------------------------------------------------------------------<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># --- Add an hour long appointment to the Outlook calendar (starting from the current date/time) ---</span>
startDate       = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
endDate         = startDate <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3600</span>  <span style="color:#008000; font-style:italic;"># endDate is one hour after the startDate</span>
newAppointment  = <span style="color:#6666ff; font-weight:bold;">Struct::AppointmentInfo</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">&quot;Example Subject&quot;</span>, <span style="color:#996600;">&quot;Example description&quot;</span>, startDate, endDate, <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;
CreateOutlookAppointment<span style="color:#006600; font-weight:bold;">&#40;</span> newAppointment, <span style="color:#996600;">&quot;work, school&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;DONE&quot;</span></pre></td></tr></table></div>

<p><script src="js/shCore.js"></script> <script src="js/shBrushCSharp.js"></script><br />
<script src="js/shBrushXml.js"></script> <script type="text/javascript"><!--
dp.SyntaxHighlighter.ClipboardSwf = '/flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
// --></script>The code demonstrates how to list all existing appointments in an Outlook calendar as well as how to add new ones programmatically.  As a note, this script does not account for recurrences (appointments which repeat) or all-day events.  However, it does provide a starting point for taking control of your Outlook calendar through Ruby.</p>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=112</wfw:commentRss>
		</item>
		<item>
		<title>Dad Strength Postmortem</title>
		<link>http://qiroka.com/dev/blog/?p=84</link>
		<comments>http://qiroka.com/dev/blog/?p=84#comments</comments>
		<pubDate>Sat, 03 Oct 2009 11:42:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[SFII90]]></category>

		<category><![CDATA[Video Games]]></category>

		<guid isPermaLink="false">http://qiroka.com/dev/blog/?p=84</guid>
		<description><![CDATA[
Dad Strength is a comedic beat &#8216;em up video game modeled after old-school titles such as Double Dragon and Final Fight.  In this postmortem, the game&#8217;s development process will be examined in depth.  Dad Strength was developed over the course of two years, and luckily a developer&#8217;s diary was maintained throughout this time.

I. Music-based Brainstorming
Music [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><img class="aligncenter" title="Dad Strength" src="http://qiroka.com/video_games/images/dad_strength_00.png" alt="" width="440" height="176" /></p>
<p><strong>Dad Strength</strong> is a comedic beat &#8216;em up video game modeled after old-school titles such as Double Dragon and Final Fight.  In this postmortem, the game&#8217;s development process will be examined in depth.  Dad Strength was developed over the course of two years, and luckily a developer&#8217;s diary was maintained throughout this time.</p>
<p style="text-align: left;"><span id="more-84"></span></p>
<p><strong>I. Music-based Brainstorming</strong></p>
<p>Music is an incredibly inspirational catalyst for my imagination.  There are particular songs whose moods alone can convey a rich visual representation, and I often find myself puzzling over how one might adapt these into an interactive medium such as a video game.  In fact, most of the game play mechanics I have designed find their origins in the attempt to integrate music and sound into an interactive form without diluting the identity of the music.  The goal is therefore not quite a holistic medium; Players should be able to enjoy the music as a separate experience from that of playing the game.</p>
<p>Lately, I&#8217;ve been increasingly interested in the do-it-yourself (DIY) mentality.  My friends and I often write and record our own songs, and sometimes the results are quite poignant (to me, at least).  My brother in particular writes some <a href="http://www.youtube.com/watch?v=glloKOyoybE">fairly unique music</a>.  He came to visit me in Washington D.C. during the summer of 2007, and we wound up creating a few short loops in Garageband using existing samples.  It was nothing more than automatic creation through experimentation, but the results spoke clearly to us both.  In listening to what amounted to nothing more than a few seconds&#8217; worth of music, we could wholly conceptualize a simple, beat &#8216;em up video game reminiscent of those of early 90&#8217;s.  We explored our imaginations for exactly what kind of game the music could suit, and the foundations for Dad Strength were soon born.</p>
<p><strong>II. Design, Pre-production, and Development<br />
</strong></p>
<p>The initial design for Dad Strength was very minimalistic.  The game would consist of the main character, two or three enemy characters, a scrolling background, and possibly a blunt weapon that could be picked up and swung about.  When thinking about game development, I generally try to wear a programmer&#8217;s hat in order to maximize code reuse whenever possible.  I realized that if Dad Strength was designed carefully, many of its components could be slightly altered for re-use in other game genres such as a 2D fighting game, side-scrolling platformer, or vertical-scrolling space shooter.  I kept this in mind while sketching out each of the game building blocks such as the character entity and the health bars.</p>
<p>In order to save time and avoid relying on programmer art, it was decided that sprite-sheets would be developed by filming live actors and extracting key frames.  The actors were filmed performing a variety of motions before a green screen.  The film was then digitally edited using a chroma key to extract the characters from the background.  This approach worked well and also lent itself to creating sprites whose image fidelity fit within the game&#8217;s 16-bit nostalgia aesthetic.</p>
<p>There were many times during development that, due to various technological problems, I felt like a decisive barrier had been reached.  In fact, there were spans of months where no progress would be made at all, which was quite depressing.  From time to time, I would entertain the idea of calling it day.  During these slumps, it became increasingly difficult to become motivated about the final product when it seemed to be nothing more than a concept.  However, I was fortunate enough to have had a continuous flow of positive support from friends and family.  Coupled with the raw desire to play the game myself, I found the energy to follow Dad Strength&#8217;s development to completion.  Of course, sacrifices and concessions had to be made during the course of its development, yet it is incredibly satisfying when a project surviving on passion alone is finally released for others to enjoy.</p>
<p><strong>III. What Went Right</strong></p>
<p>Comedy.</p>
<p>The game is, in many ways, a parody of the simpler beat &#8216;em up games of the early 90&#8217;s.  There is literally no back-story, character development, nor plot to be found in Dad Strength.  The game stars a middle-aged father figure fighting random foes (of which there are apparently a full supply of identical twins) for no specific reason.  The justification for developing this game can be boiled down to wanting to add a strong entry in my personal game development portfolio, and the game makes no attempt to hide this.  It is a simple game, and its essence lies not in revolutionary game-play nor stunning graphics; It is primarily a demonstration of my programming abilities in the guise of entertainment.</p>
<p>The premise of the game is absurd enough; However, the dialog acts as another supporting pillar of its comedy.  The game opens with the FBI anti-drug warning so commonly associated with arcade cabinets of the 80&#8217;s.  The titular character then saunters across the screen and promptly warns the player by saying, &#8220;Because I said so!&#8221;  In the first few seconds, the tone of the game is established and continues all the way through enemy death cries such as &#8220;Et tu, Dad?&#8221;.</p>
<p>The game is truly a one-dimensional beat &#8216;em up in the sense that the player can choose to move left or right along the horizontal axis yet has no control over the vertical axis.  To keep players from being bored or frustrated with this design choice, it was necessary to make the content engaging and justify repeat playability.  I chose to achieve this through a mixture of comedy and absurdity.</p>
<p><strong>IV. What Went Wrong</strong></p>
<p>In general, I wrote no technical specification documents to guide the development of Dad Strength.  There were but a few well-defined goals, milestones, and self-imposed deadlines to provide perspective on its progress.  This was largely due to the fact that Dad Strength was a project being developed on weekends and during lunch breaks.  Furthermore, I was developing the underlying technology in tandem with the game itself.  Dad Strength runs on the SFII90 engine whose development goals changed specifically to meet the vague design goals of a side-scrolling game - namely Dad Strength.</p>
<p>A significant consequence of having but a page of technical guidelines was the continuous miscalculation of time requirements.  For example, the character artwork was captured using live video in the effort to save time associated with creating detailed sprite artwork.  Nevertheless, the art pipeline used for processing video data to a final sprite-sheet took no less than four months.  Regarding the programming side of production, better and more robust methods of implementation were constantly being discovered during development, and the fundamental building blocks of the game were revised multiple times.</p>
<p><strong>V. Lessons Learned</strong></p>
<p>Throughout the development of Dad Strength, a number of my friends were eager to hear of its progress.  Some of these friends are incredible artists and others seasoned coders.   In retrospect, I feel that I should have asked them to lend me their expertise and, in doing so, matured the Dad Strength development team from a one-person project to a small team of three or four with specialized skills.  This would have undoubtedly decreased the production time and created an enjoyable team dynamic at the same time.  For subsequent projects of a comparable scope, I intend to work toward making the process a more collaboratively-driven effort.</p>
<p>Speaking specifically to the game&#8217;s programming process, I have found that after deciding upon the core game mechanics, the programming itself should focus on creating a library of reusable, extensible components.  In essence, this is akin to creating a level editor as opposed to a set number of levels.  Keeping in mind the &#8220;big picture&#8221; is crucial for when design documents change and it becomes necessary to modify or scrap the content of any previous iterations.  Case in point: The Ruby scripts for Dad Strength were completely re-written at least three times.  Each time, the design became better organized, less inter-dependent, and easier to maintain.  The cost I paid for each revision was a few more months in a world without unjustified Dad on goon violence.</p>
<p>For those interested, Dad Strength may be downloaded from here: <a href="http://qiroka.com/video_games/files/Dad_Strength.exe">Dad Strength</a>.</p>
<p><strong>VI. Supplementary Media</strong></p>
<p style="text-align: left;">The following is a collection of Dad Strength related media.  Most of the media provided highlight the development of the in-game sprites and associated hit detection logic.</p>
<p style="text-align: center;">
<p><center><iframe src="http://qiroka.com/dev/dad_strength/dad_strength_media_player.html" frameborder="0" width="400" height="500"></iframe></center></p>
<p><strong>VII. Miscellaneous Dad Strength Information</strong></p>
<li><em>Development Team Size</em>: 1</li>
<li><em>Development Time</em>: 25 months (Approximately 6 man-months)</li>
<li><em>Production Budget</em>: $350</li>
<li><em>Platforms</em>: Windows XP / Vista / 7</li>
<li style="text-align: left;"><em>Software/Tools Used</em>: Adobe Premiere, Adobe Photoshop CS4, AltoMP3 Gold, Crimson Editor, Microsoft Visual Studio 2008 Express, SFII90 (video game engine)</li>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=84</wfw:commentRss>
		</item>
		<item>
		<title>Managing Manifests and Dependencies Under Visual Studio</title>
		<link>http://qiroka.com/dev/blog/?p=59</link>
		<comments>http://qiroka.com/dev/blog/?p=59#comments</comments>
		<pubDate>Wed, 01 Apr 2009 23:41:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[SFII90]]></category>

		<guid isPermaLink="false">http://qiroka.com/dev/blog/?p=59</guid>
		<description><![CDATA[
When building an executable under Microsoft Visual Studio (either the 2005 or 2008 edition), an accompanying manifest file is generated.  The purpose of this file is to describe various dependencies of the executable such as DLLs.  The manifest file is typically baked directly into the executable itself, but alternatively it can exist as an external [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Manifest Hell Awaits" src="http://qiroka.com/blogs/dev/images/manifest_hell_awaits.png" alt="" width="440" height="167" /></p>
<p>When building an executable under Microsoft Visual Studio (either the 2005 or 2008 edition), an accompanying <a title="manifest file" href="http://msdn.microsoft.com/en-us/library/1w45z383(VS.71).aspx">manifest file</a> is generated.  The purpose of this file is to describe various dependencies of the executable such as DLLs.  The manifest file is typically baked directly into the executable itself, but alternatively it can exist as an external XML file.  In externalizing an application&#8217;s dependency information, developers can explicitly control which versions of the dependent files are to be used.  One major benefit of this design is that various versions of a dependency can exist simultaneously (<a title="Side-by-side assemblies" href="http://msdn.microsoft.com/en-us/library/ms229072(VS.80).aspx">Side-by-side assemblies</a> as Microsoft calls them) and thus different programs need not use the same version of the dependency files.  This is a great idea in theory as it would eliminate the problem of keeping system DLLs in sync, a process affectionately known as <a title="DLL Hell" href="http://www.itwriting.com/blog/?postid=261">DLL Hell</a>.  However, there are still a few quirks of manifest files that can drive developers and users alike mad.<span id="more-59"></span></p>
<p>For the past few years, I&#8217;ve been developing a 2D video game engine called <a title="SFII90" href="http://code.google.com/p/sfii90/">SFII90</a>.  The engine was initially developed under Visual Studio 2005 on Windows XP and later migrated to Visual Studio 2008.  When the initial release was ready to be deployed, I ran into a few problems running the application on other operating systems (specifically Windows Server 2003).  Despite installing the VS2005 redistributable components on these systems, I was greeted with error dialogs similar to the following:</p>
<p><img class="alignnone" title="Program error due to an invalid manifest file" src="http://qiroka.com/blogs/dev/images/program_error.png" alt="" width="426" height="80" /></p>
<p>After learning that the problem was due to a misconfiguration regarding the application manifest file, I spent quite some time searching online for suggested resolutions.  What I eventually found was that I was suffering from a few issues.  Most notably, the manifest file required msvcr80d.dll (the debug version of the C run-time library), although this was not being used by my application nor was it included in the redistributable package (Microsoft only allows release mode binaries to be distributed to users).  I used a very helpful tool known as <a title="Dependency Walker" href="http://www.dependencywalker.com/">Dependency Walker</a> to verify that the application did not require the debug library:</p>
<p><img class="alignnone" title="Dependency Walker" src="http://qiroka.com/blogs/dev/images/depends.png" alt="" width="576" height="420" /></p>
<p>I could confirm that the application did not rely on the debug CRT library msvcr80d.dll.  Regardless, every time I built the application, the manifest listed it as a dependency.  I finally realized that the application itself did not require the debug library but that <em>some of its dependents were in fact dependent on the debug library</em>.  The project included a few DLLs that I had built from source such as <a title="FreeType" href="http://www.freetype.org/">FreeType</a> and <a title="Vorbis" href="http://www.vorbis.com/">Vorbis</a>.  These had apparently been built as debug libraries under VS2005.  Even after migrating to VS2008, these libraries required the VS2005 debug CRT library which explained why the main application was requesting the debug library.  After rebuilding all of the DLLs in release mode under VS2008, the references to msvcrt80.dll in the manifest file disappeared.  At that point, my external manifest file &#8220;SFII90.exe.manifest&#8221; looked like the following:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"&gt;
  &lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"&gt;
    &lt;security&gt;
      &lt;requestedPrivileges&gt;
        &lt;requestedExecutionLevel level="asInvoker" uiAccess="false"&gt;&lt;/requestedExecutionLevel&gt;
      &lt;/requestedPrivileges&gt;
    &lt;/security&gt;
  &lt;/trustInfo&gt;
  &lt;dependency&gt;
    &lt;dependentAssembly&gt;
      &lt;assemblyIdentity type="win32" name="<strong>Microsoft.VC90.CRT</strong>" version="<strong>9.0.21022.8</strong>" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"&gt;&lt;/assemblyIdentity&gt;
    &lt;/dependentAssembly&gt;
  &lt;/dependency&gt;
&lt;/assembly&gt;</pre>
<p>The important part of the manifest file above is where the name of the dependent manifests and their versions are defined.  In this case, the name of the sole dependency is &#8220;Microsoft.VC90.CRT&#8221;, so the accompanying manifest file must be &#8220;Microsoft.VC90.CRT.manifest&#8221;.  This file can typically be found as part of the Windows side-by-side assembly manifests under <em>C:\Windows\winsxs</em>.  It is critical that the version of the CRT manifest matches that defined in the main application&#8217;s manifest (in this case, the version is 9.0.21022.8).  The following illustrates an example of the contents of such a manifest file:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"&gt;
    &lt;noInheritable&gt;&lt;/noInheritable&gt;
    &lt;assemblyIdentity type="win32" name="<strong>Microsoft.VC90.CRT</strong>" version="<strong>9.0.21022.8</strong>" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"&gt;&lt;/assemblyIdentity&gt;
    &lt;file name="<strong>msvcr90.dll</strong>" hashalg="SHA1" hash="e0dcdcbfcb452747da530fae6b000d47c8674671"&gt;&lt;asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"&gt;&lt;dsig:Transforms&gt;&lt;dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"&gt;&lt;/dsig:Transform&gt;&lt;/dsig:Transforms&gt;&lt;dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/dsig:DigestMethod&gt;&lt;dsig:DigestValue&gt;KSaO8M0iCtPF6YEr79P1dZsnomY=&lt;/dsig:DigestValue&gt;&lt;/asmv2:hash&gt;&lt;/file&gt;
    &lt;file name="<strong>msvcp90.dll</strong>" hashalg="SHA1" hash="81efe890e4ef2615c0bb4dda7b94bea177c86ebd"&gt;&lt;asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"&gt;&lt;dsig:Transforms&gt;&lt;dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"&gt;&lt;/dsig:Transform&gt;&lt;/dsig:Transforms&gt;&lt;dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/dsig:DigestMethod&gt;&lt;dsig:DigestValue&gt;ojDmTgpYMFRKJYkPcM6ckpYkWUU=&lt;/dsig:DigestValue&gt;&lt;/asmv2:hash&gt;&lt;/file&gt;
    &lt;file name="<strong>msvcm90.dll</strong>" hashalg="SHA1" hash="5470081b336abd7b82c6387567a661a729483b04"&gt;&lt;asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"&gt;&lt;dsig:Transforms&gt;&lt;dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"&gt;&lt;/dsig:Transform&gt;&lt;/dsig:Transforms&gt;&lt;dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/dsig:DigestMethod&gt;&lt;dsig:DigestValue&gt;tVogb8kezDre2mXShlIqpp8ErIg=&lt;/dsig:DigestValue&gt;&lt;/asmv2:hash&gt;&lt;/file&gt;
&lt;/assembly&gt;</pre>
<p><img class="alignnone" title="Manifest Files" src="http://qiroka.com/blogs/dev/images/manifest_files.png" alt="" width="480" height="360" /></p>
<p>All of the manifest files and DLLs being referenced should be placed in the same directory as the main application.  To summarize, dealing with manifest files is not too difficult, but due to seemingly erroneous dependencies and version incompatibilities, they can be intimidating to configure properly.  For this reason, I suggest externalizing the manifest files (this can be done in Microsoft Visual Studio by naviating to Project Properties -&gt; Linker -&gt; Manifest File -&gt; Allow Isolation and setting the value to &#8220;Yes&#8221;) and resolving dependency issues using Dependency Walker.</p>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=59</wfw:commentRss>
		</item>
		<item>
		<title>The $300 MadWorld Review</title>
		<link>http://qiroka.com/dev/blog/?p=38</link>
		<comments>http://qiroka.com/dev/blog/?p=38#comments</comments>
		<pubDate>Tue, 24 Mar 2009 05:29:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://qiroka.com/dev/blog/?p=38</guid>
		<description><![CDATA[




For those following the most current video game releases, MadWorld should need no introduction.  In a nutshell, Madworld offer players a highly stylized, film noir environment in which to creatively torture and execute an assortment of grotesque and supernatural foes.  The central controversies surrounding the game relate to its sole target platform - the Nintendo [...]]]></description>
			<content:encoded><![CDATA[<div class="mceTemp">
<dl class="wp-caption alignnone" style="width: 450px;">
<dt class="wp-caption-dt"><img title="MadWorld" src="http://www.qiroka.com/blogs/dev/images/madworld_little_eddie.png" alt="MadWorld" width="440" height="167" /></dt>
</dl>
</div>
<p>For those following the most current video game releases, <a title="MadWorld" href="http://www.gamespot.com/wii/action/madworld/index.html">MadWorld</a> should need no introduction.  In a nutshell, Madworld offer players a highly stylized, film noir environment in which to creatively torture and execute an assortment of grotesque and supernatural foes.  The central controversies surrounding the game relate to its sole target platform - the Nintendo Wii.  Before the game&#8217;s release, critics and fanboys have mainly argued the following points:</p>
<ol>
<li>The Nintendo Wii is not technically powerful enough to provide the intended experience.</li>
<li>The family-friendly Wii will become a liability for children due to MadWorld&#8217;s vulgarity and excessive violence.  This could also create an opportunity for similar games to be published without Nintendo showing any concern for morality obligations.</li>
</ol>
<p>Simply and objectively put, the first argument is fallacious because the MadWorld developers specifically chose Wii as their target platform due to its unique motion controls (see: <a title="Why MasWorld is Wii-only" href="http://games.kikizo.com/news/200903/madworld-atsushi-inaba-chat.asp" target="_self">Why MadWorld is Wii-only</a>).  The second argument is dismissible due to the existence of Mature Wii games (<a title="Manhunt 2" href="http://www.gamespot.com/wii/action/manhunt2/index.html">Manhunt 2</a>, <a title="No More Heroes" href="http://www.gamespot.com/wii/action/heroes/index.html">No More Heroes</a>) as well the illogical implication that Nintendo has a social responsibility to prevent adult content from gracing its consoles.  The &#8220;Mature&#8221; rating on MadWorld&#8217;s cover should be the first clue to parents of young children that <a title="Super Mario Galaxy" href="http://www.gamespot.com/wii/action/supermario128/index.html">Super Mario Galaxy</a> might be a better choice.</p>
<p>MadWorld was the first release developed by <a title="Platinum Games" href="http://www.platinumgames.co.jp/">Platinum Games</a>, a relatively new company formed by many of the ex-members of the dissolved Clover Studio (Viewtiful Joe, Okami).  Since I&#8217;m a huge fan of their Playstation2 beat &#8216;em up throwback <a title="God Hand" href="http://en.wikipedia.org/wiki/God_hand">God Hand</a>, I&#8217;ve been eagerly awaiting MadWorld&#8217;s release since it was unveiled last year.  However, when the game was released, my Wii was inaccessible; My father had kidnapped it to play Guitar Hero World Tour.  At the same time, I was facing the decision to have surgery to correct a level III+ acromioclavicular separation.  The total time needed to completely heal from surgery and rehabilitation is 4-6 months, so it wasn&#8217;t a light decision.  With the surgery date looming only three days away and no way to play my copy of MadWorld, I went insane and I did the only thing I could.</p>
<p><span id="more-38"></span> I had waited patiently for a few years so that I could play Platinum&#8217;s follow-up to Okami, and the thought of waiting another two or three months made me both angry and frustrated.  Even knowing that I&#8217;d only have the chance to play MadWorld for a few hours before having surgery, I opted to buy a Wii and play what I could with the short amount of time remaining.</p>
<div class="mceTemp">
<dl class="wp-caption alignnone" style="width: 450px;">
<dt class="wp-caption-dt"><img title="Level III+ Acromioclavicular Separation" src="http://qiroka.com/blogs/dev/images/shoulder_separated.jpg" alt="Level III+ Acromioclavicular Separation" width="440" height="311" /></dt>
</dl>
</div>
<p>Initially, I was very impressed with the production values, but after 15 minutes or so, I became disappointed (and borderline bored) with the gameplay.  I soon realized that this was because I was unconsciously expecting God Hand 2, of which MadWorld certainly is not.  Whereas God Hand is frantic and demands fast reflexes, MadWorld is a bit more strategic and rewards players for stringing together brutal combo attacks.  Two other fairly large aspects of this game that deserve mention are its self-referential hip-hop soundtrack and its over-the-top sportscaster banter.  While I appreciate the freshness of these aural elements, they tended to grate after much repetition.  Thankfully, Platinum has allowed the user to customize the volume of each individual auditory stream.  Playing through MadWorld with only its sound effects is in some ways eerier and more satisfying.</p>
<p>After only a few hours of game play, MadWorld did grow on me.  I was able to complete half of the game in about two and a half hours, so my experience mirrors that of many critics whom note the brevity of the game.  The game itself is not without flaws and annoyances, but it deserves a solid B for its style, direction, and relentless originality.  I wouldn&#8217;t say that MadWorld is a &#8220;must play&#8221; game for Wii, but it is certainly a gem for those seeking a fun, polished beat-em-up with a sadistic streak.  Platinum Games looks to have a bright future as innovative developers, and I can&#8217;t wait to see what other worlds they can create.  So, was it worth buying a Wii simply to play MadWorld for three hours?  Surprisingly, I&#8217;m going to say &#8220;<strong>yes</strong>&#8220;.  Although, it&#8217;s possible that it&#8217;s just the painkillers talking.  <strong>84/100</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=38</wfw:commentRss>
		</item>
		<item>
		<title>Experimental Video Games</title>
		<link>http://qiroka.com/dev/blog/?p=16</link>
		<comments>http://qiroka.com/dev/blog/?p=16#comments</comments>
		<pubDate>Fri, 27 Feb 2009 03:13:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[SFII90]]></category>

		<category><![CDATA[Video Games]]></category>

		<guid isPermaLink="false">http://qiroka.com/dev/blog/?p=16</guid>
		<description><![CDATA[
While developing a humble beat &#8216;em up game (an homage to such classics as Final Fight and Turtles in Time), I found myself in need of a way to organize various scenes.  The game would start with a loading screen, transition into a short narrative, and finally cut to the title screen.  Once the actual [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a href="http://qiroka.com/video_games/files/beatboy_1.0.exe"><img class="aligncenter" title="beatboy" src="http://www.qiroka.com/video_games/images/beatboy_00.png" alt="beatboy" width="440" height="167" /></a></p>
<p style="text-align: left;">While developing a humble beat &#8216;em up game (an homage to such classics as <a title="Final Fight" href="http://en.wikipedia.org/wiki/Final_Fight" target="_blank"><em>Final Fight</em></a> and <a title="Turtles in Time" href="http://en.wikipedia.org/wiki/Turtles_in_time" target="_blank"><em>Turtles in Time</em></a>), I found myself in need of a way to organize various scenes.  The game would start with a loading screen, transition into a short narrative, and finally cut to the title screen.  Once the actual gameplay began, another scene would be needed to keep track of the entities, images, sounds, and other game-related objects for stage one.  In keeping with the ethics of <a title="Object Oriented Programming" href="http://en.wikipedia.org/wiki/Object_oriented_programming" target="_blank">object-oriented programming</a>, I decided to make the scenes themselves objects by creating a <strong>scene </strong>entity with methods for loading, activation, deactivation, and unloading.</p>
<p style="text-align: left;">Lately, I&#8217;ve been wondering if I haven&#8217;t developed a bit of <a title="ADHD" href="http://en.wikipedia.org/wiki/Adult_attention-deficit_disorder" target="_blank">ADHD</a>.  I have a handful of game ideas that I want to explore and the list keeps growing.  The problem I&#8217;m facing is how to choose the best ideas and spend time turning them into projects.  When I completed the <strong>scene </strong>entity (which took very little time), I made the decision to design a small game to test its usefulness (which took much more time).  It turns out that the <strong>scene </strong>entity has very little to do with the final game, yet I am left with something much more satisfying.<span id="more-16"></span></p>
<p style="text-align: left;">It took around 12 hours of development (over the course of a month) to create a small game called <strong>beatboy</strong>.  The fundamental principle of <strong>beatboy </strong>is that it is not actually a video game.  I consider it more of a toy than a video game.  There are no goals, no scores, no time limits, and is meant for players to customize it with their own sound samples to tailor their own experiences.  I was inspired to create such a game by observing how a 4-year-old attempted to play a video game; it seemed that getting a colorful reaction to pressing buttons was more fun than trying to learn the rules.  I wanted to create a game that a child could idly &#8220;play&#8221; and yet somehow still appeal to adults.</p>
<p style="text-align: left;">Of course, there are already game developers aiming to explore unconventional gameplay, abstract themes, and experimental styles.  Using these types of games as reference points, I have tried to keep <strong>beatboy </strong>minimalist and usable.  In particular, I find the works of the following game designers fascinating:</p>
<p style="text-align: left;">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="482" height="299" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/d3v6npP8OZk&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="482" height="299" src="http://www.youtube.com/v/d3v6npP8OZk&amp;hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: left;"><a title="Electroplankton" href="http://en.wikipedia.org/wiki/Electroplankton" target="_blank">Electroplankton</a> / Nintendo DS / 2006 / Designer: Toshio Iwai-san (<span style="font-weight: normal;"><span class="t_nihongo_kanji"><span lang="ja" xml:lang="ja">岩井俊雄さん)</span></span></span></p>
<p style="text-align: left;">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="482" height="297" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/nwNdTdtyXAM&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="482" height="297" src="http://www.youtube.com/v/nwNdTdtyXAM&amp;hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: left;"><a title="Noby Noby Boy" href="http://en.wikipedia.org/wiki/Noby_Noby_Boy" target="_blank">Noby Noby Boy</a> / Playstation3 / 2009 / Designer: Keita Takahashi-san (高橋 慶太<span style="font-weight: normal;"><span class="t_nihongo_kanji"><span lang="ja" xml:lang="ja">さん)</span></span></span></p>
<p style="text-align: left;">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="484" height="297" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ojirw9s_si4&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="484" height="297" src="http://www.youtube.com/v/ojirw9s_si4&amp;hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: left;"><a title="I Wish I Were the Moon" href="http://www.ludomancy.com/blog/2008/09/03/i-wish-i-were-the-moon/" target="_blank">I Wish I Were The Moon</a> / PC / 2008 / Designer: Daniel Benmergui</p>
<p style="text-align: left;">
<div class="mceTemp">
<dl class="wp-caption alignnone" style="width: 405px;">
<dt class="wp-caption-dt"><img title="The Marriage" src="http://qiroka.com/blogs/dev/images/the_marriage.png" alt="The Marriage" width="395" height="432" /></dt>
</dl>
</div>
<p style="text-align: left;"><a title="The Marriage" href="http://www.rodvik.com/rodgames/marriage.html" target="_blank">The Marriage</a> / PC / 2007 / Designer: Rod Humble</p>
<p style="text-align: left;">
<p style="text-align: left;">It is a very exciting time for experimental game design.  The video game industry as a whole is undeniably maturing at an incredible rate, and I feel that these games illustrate the stepping stones into a new arena of gaming.</p>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=16</wfw:commentRss>
		</item>
		<item>
		<title>SFII90 - C++ and Ruby Video Game Engine - 0.1.0 Released!</title>
		<link>http://qiroka.com/dev/blog/?p=5</link>
		<comments>http://qiroka.com/dev/blog/?p=5#comments</comments>
		<pubDate>Wed, 17 Dec 2008 06:12:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[SFII90]]></category>

		<guid isPermaLink="false">http://qiroka.com/blogs/dev/?p=5</guid>
		<description><![CDATA[
My name is Phillip Weisberg and I&#8217;m a software developer in the Washington, D.C. area.  Welcome to fiber-optic megawatts!  This blog will focus mainly upon video games - from reviews through development and anything else along the way.  Today&#8217;s topic is SFII90 - a free video game engine that I developed in C++ and Ruby [...]]]></description>
			<content:encoded><![CDATA[<p><div class="wp-caption aligncenter" style="width: 450px"><a href="http://code.google.com/p/sfii90/"><img title="SFII90 - C++ and Ruby Video Game Engine" src="http://www.qiroka.com/blogs/dev/images/splash_SFII90.png" alt="SFII90 - C++ and Ruby Video Game Engine" width="440" height="167" /></a><p class="wp-caption-text">SFII90 - C++ and Ruby Video Game Engine</p></div></p>
<p>My name is Phillip Weisberg and I&#8217;m a software developer in the Washington, D.C. area.  Welcome to <strong>fiber-optic megawatts</strong>!  This blog will focus mainly upon video games - from reviews through development and anything else along the way.  Today&#8217;s topic is <strong>SFII90 </strong>- a free video game engine that I developed in C++ and Ruby and licensed under the <a class="wp-caption-dd" title="GNU LGPL 2.1" href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" target="_self">GNU LGPL 2.1</a>.  Before I jump too far ahead, let me first give you a little background about myself and the how the engine came to be.</p>
<p>I&#8217;ve always been interested in designing and producing video games.  I made a few demos in 2005, but I wasn&#8217;t satisfied with how horribly inefficient they were; There was almost no reusable code nor consistent design from game to game.  I looked at the top ten or twenty engines available for hobbyists and for some reason or another was not satisfied with any of them.  I thought it might be a good idea to create my own video game engine (despite some foreboding comments on<a class="wp-caption-dd" title="Gamedev" href="http://gamedev.net/" target="_self"> www.gamedev.net</a>), so I started by designing a small system that could draw sprites from bitmap files and load OGG Vorbis files.  It was&#8230; <em>better</em>, but still not very good.<span id="more-5"></span></p>
<p>In the winter of 2006, I decided to take a serious approach at researching how to design a modular, easy-to-use video game engine.  I considered as many aspects of the engine as I could before commiting to development specifics such as languages and target platforms.  After about a year of scribbling notes on pieces of scrap paper and pizza boxes, I felt I was ready to start coding.  One of my core goals was to design a system that was as straightforward as possible and encouraged developers (and even players) to toy with the game code itself and see what they could discover.  If I structured the engine and scripting language API as clear as possible, perhaps it could intrigue a few gamers into modifying/customizing the games they play.  With this in mind, I decided to sacrifice speed for the sake of simplicity.</p>
<p>I knew that programming games with my engine would also need to be <em>fun</em>.  How could that be possible?  It just so happens that at that time I was learning a scripting language called <a class="wp-caption-dd" title="Ruby" href="http://ruby-lang.org/">Ruby</a>.  Its design philosophy was remarkably similar to mine - focus on the developers, not the machines.  Computers can always get faster.  Memory is cheap.  A high-level programming language should be simple, follow the Principle of Least Surprise (POSS, though definitely related to KISS), and most of all enjoyable!  I found this to be the case when developing with Ruby, so I decided to integrate it into my engine as the scripting language.  I wrote a framework around it to handle entities, device input, and finite state machines.</p>
<p>By the summer of 2008, the engine was in a stable state and was ready to be tested.  A few colleagues and friends of mine suggested forming a game development team to enter the &#8220;Games for Health Game Jam&#8221;.  The contest focused on creating a game in a 24-hour period that related to personal health and safely controlling one&#8217;s <a class="wp-caption-dd" title="Body Mass Index" href="http://en.wikipedia.org/wiki/Body_mass_index" target="_self">body mass index</a> (BMI).  It was sponsored by the <a class="wp-caption-dd" title="Games for Health" href="http://www.gamesforhealth.org/" target="_self">Games for Health Initiative</a> and the <a class="wp-caption-dd" title="Robert Wood Johnson Foundation" href="http://www.rwjf.org/" target="_self">Robert Wood Johnson Foundation</a>.  There were six teams that entered and competed for a total of $4,000 in cash prizes.  The contest was a great experience and there were a lot of really innovative entries.</p>
<p><div class="wp-caption aligncenter" style="width: 394px"><a href="http://www.gamesforhealth.org/archives/000232.html"><img title="Games for Health 2008" src="http://www.gamesforhealth.org/images/health-game-jam-october-2008-8.jpg" alt="Games for Health Game Jam 2008 - Baltimore, MD" width="384" height="288" /></a><p class="wp-caption-text">Games for Health Game Jam 2008 - Baltimore, MD</p></div></p>
<p>After everyone presented their games, the judges exited the auditorium to confer.  They returned shortly to announce that my team and I had won the grand prize for our entry &#8220;150 A Day&#8221;.  We were incredibly happy to have won the game jam, and I was particularly happy that the game had been developed using SFII90.  It had passed an important test.  However, the experience had taught me a few things about using the engine.  Most notably, it was difficult for other developers to get the hang of it without any documentation.  Since I had always been a lone developer on this project, I definitely neglected this aspect.</p>
<p>For the next two months, I worked on documenting all of the C++ engine as well as the Ruby framework.  I also added a much needed logging utility to tell developers which lines of Ruby script cause problems.  The Game Jam was a great experience because it showed me quite clearly that an engine (no matter how complex or simple) is useless without proper documentation.  I also realized that it would be very helpful to add a set of &#8220;common&#8221; objects, or entities, to the distribution of SFII90.  There are now classes that are distributed as part of SFII90 for creating animated sprites, frames per second (FPS) counters, and joystick bindings.</p>
<p>So today, after a total of possibly three years, I released the first version of SFII90.  I&#8217;m excited to see what people can create with it, and I welcome your feedback and suggestions.  SFII90 has come a long way since being a simple bitmap and OGG audio file loader, but of course there is still much more work to be done. <img src='http://qiroka.com/dev/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://qiroka.com/dev/blog/?feed=rss2&amp;p=5</wfw:commentRss>
		</item>
	</channel>
</rss>
