<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>psychicsoftware | Category Archives: Techie</title>
	<atom:link href="https://www.psychicsoftware.com/category/techie/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.psychicsoftware.com</link>
	<description></description>
	<lastBuildDate>Fri, 23 Jan 2026 11:29:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1</generator>
	<item>
		<title>Pathfinding and Pedestrian Simulation in The Necromancer&#8217;s Tale</title>
		<link>https://www.psychicsoftware.com/2026/pathfinding-and-pedestrian-simulation-in-the-necromancers-tale/</link>
		<comments>https://www.psychicsoftware.com/2026/pathfinding-and-pedestrian-simulation-in-the-necromancers-tale/#comments</comments>
		<pubDate>Fri, 23 Jan 2026 11:29:07 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Techie]]></category>
		<category><![CDATA[The Necromancer]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=1574</guid>
		<description><![CDATA[Character movement turned out to be one the more complex systems in The Necromancer’s Tale, perhaps unexpectedly (to me). I’ve been working with A* pathfinding for nearly 20 years now (having first discovered it when working on Darkwind), and have taught it to my undergrads for the past 10+ years. It’s at the core of [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Character movement turned out to be one the more complex systems in <em>The Necromancer’s Tale</em>, perhaps unexpectedly (to me). I’ve been working with A* pathfinding for nearly 20 years now (having first discovered it when working on Darkwind), and have taught it to my undergrads for the past 10+ years. It’s at the core of both in-combat and out-of-combat movement of the characters in TNT.<br />
<b></b></p>
<p>&nbsp;</p>
<h3>Hexgrids</h3>
<p>Hexes are often considered better than squares for turn-based combat games, since hexes are the same distance from each of their neighbours. My code for building these starts from a seed position, which is manually set at a walkable location, and then it searches in all 6 directions using raycasts to see which ways can be walked from this location (i.e. which directions are clear of obstacles). This adds more hexes which are then also searched &#8211; we “flood” outwards until all reachable hexes within our predefined region have been added, along with their connectivity to their neighbours.</p>
<p><img src="https://www.psychicsoftware.com/images/hex-anim.gif" alt="" /></p>
<p>This produces a graph of connected nodes, which is perfect for the A* algorithm. We also need to be able to quickly gather hexes within an arbitrary region of space (without the inefficiency of having to search outwards from the seed location to find them), so hexes are also inserted into buckets which are configured as a sparse 3D array based on 1m x 1m x 1m size. The overworld has 70,000 connected hexes, and each interior/underground location has its own hexgrid. All A* grid loading and pathfinding is performed by multiple threads.</p>
<p>&nbsp;</p>
<h3>Less Need for Invisible Walls</h3>
<p>The player has several options for how to control movement, including mouse-clicking (which uses A* pathfinding to figure out a route around obstacles) and direct WASD or joystick-based control (which does not).</p>
<p>Direct movement (WASD/joystick, where movement is constrained only by collisions) has a problem whereby players might wander away from where you want them to go, and off into the empty wilderness. By cross-referencing the player’s position with the hexgrid, I constrain the player to stay close to the nearest hex &#8211; this means there’s less need for invisible walls to stop them wandering off into the wilderness where there is no game content, or from walking inside solid objects when Unity’s rather suspect physics mesh-collisions fail.</p>
<p>&nbsp;</p>
<h3>Nice things you can do with the G (‘cost’) component of A*</h3>
<p>A* is a pretty elegant algorithm for efficiently finding the shortest path between two locations. At its core is a calculation F = G + H, which estimates the distance that a possible solution might take through a given node. The G part of this is interesting: it’s the cost of getting from a node to a neighbour. Often this is simply chosen as the Euclydean distance between the nodes, but <i>it doesn’t have to be</i>.</p>
<p>We can make the G cost higher, for example, when crossing difficult terrain. This discourages the algorithm from picking a route without actually forbidding it. In TNT, I quickly found that the townsfolk loved taking a shortcut through a graveyard, which was often a slightly shorter way of crossing the river between the north and south of the city. This didn’t feel right: the cemetery path is visibly narrow and not well-worn, and crosses a narrow bridge, while the ‘standard’ route is a wider stone bridge leading through the marketplace.</p>
<p>So I added penalty areas &#8211; regions of space for which the G cost between hexes is artificially inflated. The cemetery is an obvious place where this works well, but this approach let me fix other areas too, for example narrow gaps between pairs of houses. I also add a per-terrain-texture penalty, so that NPCs tend to walk on cobblestones in preference to grass or sand. This stopped them from taking shortcuts all the time, and kept them to routes that they visibly ‘should’ be using.</p>
<p><img src="https://www.psychicsoftware.com/images/a_star_penalty.jpg" alt="" /></p>
<p>By the way, if you’re wondering about all those white and blue boxes, they are named location markers &#8211; NPCs often move between specific locations so this was a good way to lay them out. These markers are also used in the cutscene system, allowing ‘stage directions’ to control character movements synchronised to a conversation or scene. [<a href="https://www.psychicsoftware.com/2020/how-to-kill-your-friends-and-alienate-people-the-necromancers-tale-development-update/" target="_blank">I wrote a bit about the cutscene system here</a>.]</p>
<p>&nbsp;</p>
<h3>Believable Pedestrian Movement in Crowded Environments</h3>
<p>Once I had a town full of wandering villagers, I needed to make them aware of each other so that they weren’t colliding all the time. Over the several years I was working on this, l had written various last-minute avoidance approaches (basically, over-riding their current A* path trajectory when they were about to collide) so that characters didn’t walk right through each other. It worked okay, but not great: avoidance tended to look very unaware and last-minute.</p>
<p><img src="https://www.psychicsoftware.com/images/ped-anim.gif" alt="" /></p>
<p>Here in debug mode they&#8217;re telling me about random path modifications they make when there&#8217;s other pedestrians nearby:</p>
<p><img src="https://www.psychicsoftware.com/images/ped-anim2.gif" alt="" /></p>
<p>But then I discovered the RVO (<em>Reciprocal Velocity Obstacles</em>) algorithm: see discussion [<a href="https://www.researchgate.net/profile/Dinesh-Manocha/publication/221073351_Reciprocal_Velocity_Obstacles_for_Real-Time_Multi-agent_Navigation/links/56cb391908ae5488f0daea79/Reciprocal-Velocity-Obstacles-for-Real-Time-Multi-agent-Navigation.pdf%20" target="_blank">here]</a> and [<a href="https://markus-x-buchholz.medium.com/reciprocal-velocity-obstacles-rvo-for-collision-avoidance-in-c-d7f4e7959417" target="_blank">here]</a>.</p>
<p>This provides a more elegant simulation of all moving characters, each of whom registers their intended trajectory. The paths taken by characters are then modified to avoid collisions several seconds into the future.</p>
<p><img src="https://www.psychicsoftware.com/images/ped-anim3.gif" alt="" /></p>
<p>&nbsp;</p>
<h3>One Size Does Not Fit All</h3>
<p>I had put a lot of effort (3+ years) into massaging my code and its parameters so that it worked well in all circumstances while overcoming recurring problems such as NPCs falling into holes or getting stuck on stairs (are stairs a hole when you’re going down? Are they a cliff when you’re going up?) Given the different sizes and speeds of characters, and the different steepnesses of terrain and stairs, this was a difficult task and perhaps ill-posed, i.e. lacking any single correct answer given the constraints.</p>
<p>My breakthrough came in a very simple form: I started to demarcate areas where the rules behaved differently. When walking on stairs, a character could turn off its hole-avoidance and steep ground avoidance. When going through busy narrow archways, characters could temporarily make their RVO objects thinner, so they don’t get in a muddle all trying to avoid each other. These are simply done as Triggers in Unity. When a character is inside a certain type of trigger, it runs alternative code for specific sections of its movement function.</p>
<p>&nbsp;</p>
<h3>Other Things I Have Written about Pathfinding</h3>
<p>I&#8217;ve done some other interesting things with the A* algorithm over the years. [<a href="https://www.psychicsoftware.com/2011/pathfinding-just-like-those-clever-humans/" target="_blank">Here&#8217;s one from 15 years ago]</a> with [<a href="https://www.psychicsoftware.com/redfern_gameon2011_pathfinding_paper_v02.pdf" target="_blank">an academic paper I wrote</a>]. I captured data from players in order to make computer-controlled vehicles take &#8216;sensible&#8217; routes.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2026/pathfinding-and-pedestrian-simulation-in-the-necromancers-tale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>High performance networking with a &#8216;web&#8217; of peer-peer connections in Godkin</title>
		<link>https://www.psychicsoftware.com/2018/high-performance-networking-with-a-web-of-peer-peer-connections-in-godkin/</link>
		<comments>https://www.psychicsoftware.com/2018/high-performance-networking-with-a-web-of-peer-peer-connections-in-godkin/#comments</comments>
		<pubDate>Fri, 05 Jan 2018 14:14:52 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Godkin]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=1110</guid>
		<description><![CDATA[Introduction Godkin is an in-development multiplayer co-op combat RPG, with a maximum of 4-5 players per session, and with high numbers of moving entities (4-5 players each with several AI-controlled followers; several villagers; and potentially 100s of monsters and 10s of defensive towers, missiles and spells active at a time). In order to handle the [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="http://store.steampowered.com/app/692580/Godkin/" target="_blank">Godkin</a> is an in-development multiplayer co-op combat RPG, with a maximum of 4-5 players per session, and with high numbers of moving entities (4-5 players each with several AI-controlled followers; several villagers; and potentially 100s of monsters and 10s of defensive towers, missiles and spells active at a time). In order to handle the high amount of network traffic, I have developed an infrastructure involving, at its core, a direct peer-peer connection between each pair of players in a game session.</p>
<h2>Peer-Peer Direct Connections</h2>
<p>The main motivations behind a peer-peer approach are (i) low latency, and (ii) low server costs. Using peer-peer means that a hosted server is not needed apart from initial handshaking and <a href="https://keithjohnston.wordpress.com/2014/02/17/nat-punch-through-for-multiplayer-games/" target="_blank">NAT punchthrough</a>. With 5-10 movement packets per second, per entity, per connected client, the amount of network traffic (and potential server CPU load) can grow alarmingly.</p>
<p>In my &#8216;web of direct connections&#8217; approach, the player who starts up a game session listens for incoming connections. The second player to join connects to the 1st player and then itself listens for incoming connections. This procedure continues: each player who joins connects to each existing player&#8217;s connections, and then opens its own connection for use by subsequent players. This model means that each player can send and receive data directly with each other player (a traditional client-server setup would of course mean data between players would have to be relayed via the server, i.e. 2 hops rather than 1). Latency is minimised.</p>
<p><img class="aligncenter" src="https://i.imgur.com/51pk399.png" alt="" width="397" height="424" /></p>
<p>In Godkin, we&#8217;re using <a href="https://en.wikipedia.org/wiki/WebRTC" target="_blank">WebRTC</a> data channels for both unreliable data (i.e. entity movement updates) and reliable data (i.e. game/entity states and event data).</p>
<h2>Client-Server Fallback</h2>
<p>The trickiest thing about peer-peer networking on the public internet is the fact that each client will be sitting behind a router which will probably not allow unsolicited incoming traffic, and in any case without manual configuration will not know where to route that traffic to, in its private network. The solution is <a href="https://keithjohnston.wordpress.com/2014/02/17/nat-punch-through-for-multiplayer-games/" target="_blank">NAT punchthrough</a> which involves both clients connecting to a publicly-addressable server, and then (via data from the server) negotiating connections directly to each other through the same port that the other client just opened to the server. It&#8217;s a somewhat messy process and a small fraction of routers pretty much refuse to do it. Therefore, a fallback is needed whereby clients who have failed to achieve peer-peer connection will relay data to each other via a traditional server. In Godkin, we use UDP (for unreliable data) and Websockets (for reliable data) as a fallback. The exception is the game&#8217;s public hub where there can be larger numbers of clients, with players joining/leaving at a high rate: here, we use server-relaying all the time.</p>
<p><img class=" aligncenter" src="https://i.imgur.com/b67quFAl.jpg" alt="" width="640" height="427" /></p>
<h2>Scoping</h2>
<p>The idea behind scoping is that certain data is less relevant to a player if it related to a game entity that is far away from their camera. The main data that can be culled through scoping is position updates (which are also overwhelmingly the most frequently sent types of data). Since Godkin is a 2D topdown/isometric game, it&#8217;s easy to decide whether a particular world position is visible to other players or not, assuming you know where their camera is located. If a packet is defined as &#8216;scopeable&#8217;, the sending client will typically only send it to other clients for whom it is in-scope. Every 25th packet is sent to everyone, regardless of scope. The exception is data related to Player characters, which is sent without scoping, since everyone needs to accurately know where everyone else&#8217;s camera is.</p>
<p><img class="aligncenter" src="https://i.imgur.com/yJXLuyA.gif" alt="" width="594" height="405" /></p>
<h2>Distributed Control</h2>
<p>One further system in Godkin which I have implemented for efficiency reasons is distributed control, by which I pass control of AI entities between clients based on whoever is closest to them. This means that both CPU and network loads are balanced between clients, rather than the game having a heavy reliance on the power and connectivity of the 1st player. In fact, distributed control is also a requirement in order to support scoping: we need to make sure that each client is controlling interactions between entities that are &#8216;in scope&#8217; for it, i.e. it knows their positions accurately. Since Godkin is a co-op game, we&#8217;re not overly concerned about security (although, I have implemented some anti-cheating measures).</p>
<h2>Unity3D Implementation</h2>
<p>Godkin is being developed using the <a href="https://unity3d.com/" target="_blank">Unity3D </a>engine, and I was initially developing the networking infrastructure using the excellent <a href="https://www.photonengine.com/en-US/BOLT" target="_blank">Bolt </a>plug-in. Last year, however, the company Photon bought Bolt, and implemented a punitive per-seat cost which is the same as the per-seat cost of their client-server solution, despite the fact that server overhead in a peer-peer situation is a tiny fraction of that in a client-server situation. Unhappy with this, I explored other possibilities and eventually picked a really nice, bare-bones <a href="https://assetstore.unity.com/packages/tools/network/webrtc-network-47846" target="_blank">WebRTC plug-in</a>. One of the benefits of moving to a simpler, low-level solution was also that I was able to fairly easily construct the &#8216;web of connections&#8217; approach as described above, rather than treating the 1st player as a server (which is what Bolt does).</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2018/high-performance-networking-with-a-web-of-peer-peer-connections-in-godkin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Orbs.it &#8212; an &#8220;agar.io&#8221; style game</title>
		<link>https://www.psychicsoftware.com/2017/orbs-it-agario-style-game/</link>
		<comments>https://www.psychicsoftware.com/2017/orbs-it-agario-style-game/#comments</comments>
		<pubDate>Fri, 11 Aug 2017 09:04:16 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Orbs.it]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=1055</guid>
		<description><![CDATA[Agar.io and Orbs.it A couple of years ago, agar.io was released as a browser game, and caused quite a sensation. It has subsequently spawned an entire genre of games &#8212; lightweight, massively multiplayer browser games with simple graphics and gameplay. This type of no-nonsense, easy-access multiplayer game appeals to many people, and naturally suits lone [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Agar.io and Orbs.it</h2>
<p>A couple of years ago, <a href="http://agar.io" target="_blank">agar.io</a> was released as a browser game, and caused quite a sensation. It has subsequently spawned an entire genre of games &#8212; lightweight, massively multiplayer browser games with simple graphics and gameplay. This type of no-nonsense, easy-access multiplayer game appeals to many people, and naturally suits lone developers (especially when their art skills are not great).</p>
<p>So late last year, and early this year, I developed <a href="http://www.orbs.it" target="_blank">orbs.it</a></p>
<div style="position: relative; left: -50px;"><iframe src="https://www.youtube.com/embed/guyaAmQ6Ejc?rel=0&amp;showinfo=0?ecver=2" width="600" height="386" frameborder="0" allowfullscreen="allowfullscreen"></iframe></div>
<p>Orbs is a simple to play game, yet is very skillful. It&#8217;s about fast and accurate control of your &#8220;guns&#8221;. Eight players start the game, and each initially control a single orb which is part of a set of 24 orbs encircling a central &#8220;sun&#8221;. You shoot from your orbs, and when you hit another orb you take control of it. The winner is whoever is left last in the game. It&#8217;s a very satisfying mechanic, especially when you get <em>in the flow</em> and claim orb after orb in rapid succession.</p>
<h2>Lots of users</h2>
<p>In May I released orbs.it on <a href="http://iogames.space/" target="_blank">iogames.space</a> which is the main portal for &#8220;agario-style&#8221; games. I was pleasantly surprised with the amount of players that clearly seek out this type of game &#8212; within a couple of days, my server was starting up 5-10 game sessions per minute, each with typically 4 or 5 humans in (the rest being bots). As of right now, there are nearly 90,000 player accounts in the game&#8217;s database. </p>
<h2>Server architecture</h2>
<p>Orbs proved to be a nice test-bed for the nodejs-based gameserver cluster I had developed. The central masterserver looks after player logins and communicates with gameservers which run the actual game sessions. It monitors the number of games running on each server, and dynamically starts/stops server instances as required, to deal with varying loads. There&#8217;s also some interesting requirements around things like gameserver hot-patching, so again this has involved developing useful techniques which I&#8217;m sure I will use again. I have done this sort of thing before in <a href="http://www.dark-wind.com" target="_blank">Darkwind</a> of course, but the system in Orbs is generally much slicker and didn&#8217;t suffer from the horrible nightmares of blocked sockets which afflicted Darkwind on its opening weekend on Steam.  </p>
<h2>Networking</h2>
<p>High-speed networked gaming is always a challenge to develop, and a particular challenge for &#8220;agario-style&#8221; games is that they are generally limited to using websockets for their communications. Websockets provide really handy bidirectional communication between browser and webserver, so are far better than plain-old Ajax.. however, they are still based on TCP, and that means guaranteed, ordered delivery of packets. This is the main cause of sudden spikes in latency which most Websocket games suffer from. The latency is basically unavoidable &#8211; it happens when a packet fails to deliver and has to be re-delivered, and all subsequent packets are cached on the receiver until such time as the missing packet arrives, so that they can be delivered to the receiving application in the correct order. This makes TCP fundamentally unsuitable for fast-moving data, <em>especially when the nature of the data is that late packets are irrelevant</em>. If your application knows where a player&#8217;s orb is at time 20 in a game, it really doesn&#8217;t care to know where it was at time 19, yet TCP doesn&#8217;t allow your application to see the data from time 20 until the data from time 19 is received.</p>
<h2>Deterministic positioning of orbs</h2>
<p>I wanted orbs.it to be, as far as possible, immune to the latency problems caused by TCP. I didn&#8217;t want the field of orbs to jump around and glitch on the screen, like the player-controlled entities in most agario-style game do. The solution was to remove player-control of the orbs altogether &#8211; this also fitted the design requirement of simplicity. The orbs move around in orbits, based on elliptical paths with continually changing parameters (and ultimately controlled by Sin and Cos, of course). The real trick is that these paths, although interesting and varied (leading to a continually-shifting playfield) are entirely deterministic. At any specific time after the game has started, the game server and game clients can all calculate and precisely agree on where each orb is. This vastly simplifies things and gets rid of many of the difficulties associated with everything a game client knowing about everyone else being out of date by the time they know it.</p>
<p>If you&#8217;re interested to read more about fast-paced multiplayer networking, <a href="http://www.gabrielgambetta.com/client-server-game-architecture.html" target="_blank">this is an excellent overview</a>.</p>
<p>You can play orbs straight from your browser here:  <a href="http://www.orbs.it" target="_blank">orbs.it</a>  and it&#8217;s also available on the Android and iOS app-stores, although has not seen much traction there.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2017/orbs-it-agario-style-game/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faking Shadows and Lights in a 2D &#8216;isometric&#8217; Game</title>
		<link>https://www.psychicsoftware.com/2017/faking-shadows-and-lights-in-a-2d-game/</link>
		<comments>https://www.psychicsoftware.com/2017/faking-shadows-and-lights-in-a-2d-game/#comments</comments>
		<pubDate>Tue, 09 May 2017 19:08:48 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Godkin]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=1014</guid>
		<description><![CDATA[For the past few months, I have been working on Godkin, a pixel-art online co-op combat RPG. This is a collaboration between Psychic Software and Goblin Portal (our second collaboration, in fact, following up on last year&#8217;s release Goblins &#38; Grottos). Godkin takes a &#8220;faked 3D&#8221; view (this style is often referred to as isometric, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">For the past few months, I have been working on <a title="Godkin" href="http://godkin.net/" target="_blank">Godkin</a>, a pixel-art online co-op combat RPG. This is a collaboration between <a title="Psychic Software" href="http://www.psychicsoftware.com" target="_blank">Psychic Software</a> and <a title="Goblin Portal" href="http://www.goblinportal.com/" target="_blank">Goblin Portal</a> (our second collaboration, in fact, following up on last year&#8217;s release <a title="Goblins &amp; Grottos" href="http://store.steampowered.com/app/389190/Goblins_and_Grottos/" target="_blank">Goblins &amp; Grottos</a>).</p>
<p style="text-align: justify;">Godkin takes a &#8220;faked 3D&#8221; view (this style is often referred to as isometric, although actually we&#8217;re not adhering correctly to the strict viewpoint that would make the game isometric.) Getting the lighting and shadows looking good in this style is somewhat challenging, since there&#8217;s no real 3D geometry for the game engine to work with. I&#8217;m having a lot of fun programming this game in Unity (it&#8217;s my first Unity game) and figured a blog post about shadows and lights was in order!</p>
<div style="position: relative; left: -50px;"><iframe src="https://www.youtube.com/embed/SmyV_IpmDJc" width="705" height="386" frameborder="0" allowfullscreen="allowfullscreen"></iframe></div>
<p>At the core of my shadowing system are the FakeShadowCaster and LightAnimator components.</p>
<h2>LightAnimator</h2>
<p style="text-align: justify;">A LightAnimator component is attached to any objects that have lights &#8211; camp fires, torches, explosions, etc. These search for nearby objects which have FakeShadowCaster components, and register with them. They also notify the FakeShadowCaster objects whenever changes happen (e.g. the light moving, flickering, brightening, dimming, turning off).</p>
<h2>FakeShadowCaster</h2>
<p style="text-align: justify;">A FakeShadowCaster component is attached to any objects that we need to cast shadows &#8211; basically, anything that should appear to have some 3D &#8216;height&#8217; &#8211; characters, monsters, rocks, trees. This component maintains a list of nearby light sources, and creates a fake shadow sprite to associate with each of them. Whenever a light notifies a change, or if the FakeShadowCaster itself moves, its list of shadows are re-calculated. Each shadow is rotated to face away from the associated light source, and its opacity is set based on distance from the light (plus other variables). I also wrote a &#8216;shadow skew&#8217; shader which spreads apart the vertices of the shadow sprite which are further away from<img class=" alignright" src="http://www.psychicsoftware.com/images/shadow_cast_tree_1.png" alt="Tree Shadow" /> the light source &#8211; with a stronger effect the closer it is to the light; this adds quite well to the overall feeling of 3D. Another nice touch is that we can use whatever sprites we like for the shadows &#8211; so trees, for example, can have their shape baked into their file.</p>
<h2>&#8216;3D&#8217; Object Shader</h2>
<p style="text-align: justify;">The standard Unity sprite shaders look great for terrain, and sprites which don&#8217;t have much &#8216;height&#8217; &#8211; however, since the amount that each of their pixels is lit is simply based on the distance they are from light sources, this starts to look strange for objects that are supposed to be tall. The problem is that the top pixels and bottom pixels of the object will be at quite a different distance from the light &#8211; but to look like a proper object with height, the vertical position of all pixels should be considered the same, for lighting purposes. So here we have a shader that attentuates light to all pixels based on the position of the vertically lowest ones. This shader also reduces the brightness of any object which is in front of lights (since in this case the majority of the light should be cast on the non-visible &#8216;back&#8217; of the objects).</p>
<p><img src="http://www.psychicsoftware.com/images/godkin-diffuse.jpg"> <img src="http://www.psychicsoftware.com/images/godkin-isometric.jpg"></p>
<p>If you&#8217;d like to follow the progress of Godkin&#8217;s development, here&#8217;s our <a href="https://godkinblog.tumblr.com/" title="Godkin Blog" target="_blank">blog</a>. Or why not join us for a chat in <a href="https://discord.gg/Vv6f2wn" title="Godkin Discord Channel" target="_blank">Discord</a>?</p>
<p><img src="http://www.psychicsoftware.com/images/godkin-dark-shadow.jpg"></p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2017/faking-shadows-and-lights-in-a-2d-game/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Goblins &amp; Grottos</title>
		<link>https://www.psychicsoftware.com/2015/introducing-goblins-grottos/</link>
		<comments>https://www.psychicsoftware.com/2015/introducing-goblins-grottos/#comments</comments>
		<pubDate>Tue, 12 May 2015 22:24:19 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Goblins & Grottos]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=873</guid>
		<description><![CDATA[Goblins &#38; Grottos is a new collaboration between Psychic Software (from Ireland) and Goblin Portal (from Sweden). We&#8217;re calling Goblins &#38; Grottos an &#8220;inverted RPG&#8221;. You play as the goblin, trying to escape a series of dungeon levels while a team of callous adventurers lays waste to everything around them. The idea is to turn [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Goblins &amp; Grottos is a new collaboration between <a href="http://www.psychicsoftware.com" target="_blank">Psychic Software</a> (from Ireland) and <a href="http://www.goblinportal.com" target="_blank">Goblin Portal</a> (from Sweden). We&#8217;re calling Goblins &amp; Grottos an &#8220;inverted RPG&#8221;. You play as the goblin, trying to escape a series of dungeon levels while a team of callous adventurers lays waste to everything around them. The idea is to turn normal RPGs on their heads, and see everything from the eyes of the poor helpless cannonfodder for once.</p>
<p>Goblin Portal have created a clean pixel style for the game, and I&#8217;m the programmer (of course). It&#8217;s working out well under control of a 2D physics engine: we have spent a lot of time getting the core animations and interactions with the environment as good as possible; the goblin runs, jumps and climbs walls, swings from chains as he attempts to escape the numbskull adventurers .. who in turn have no respect for the goblin, seeing him only as a quick kill for 10xp which brings them along the road to their next level and unlocking their next skill.</p>
<p><img src='http://i.imgur.com/HvudOAN.gif'></p>
<p>I&#8217;m using the same core set of technologies as I have for several recent projects: it&#8217;s written using HTML5/Javascript packaged into a desktop executable using <a href="https://github.com/nwjs/nw.js" target="_blank">nodewebkit</a> and with <a href="http://www.pixijs.com/" target="_blank">pixijs</a> for pretty efficient WebGL rendering. Nodewebkit gives access to things such as local file reading/writing, which isn&#8217;t normally possible from a browser. I&#8217;m using the <a href="http://brm.io/matter-js/" target="_blank">matterjs</a> javascript physics engine to move stuff around, but other than that there&#8217;s no actual game engine to be seen. I have found this suits me well for the 2D games I have been making lately &#8211; I can construct my own architecture rather than having to learn someone else&#8217;s; and the lightweight nature of Javascript suits me.</p>
<p>The near-term plan for Goblins &#038; Grottos is to make a playable one-level demo, and to engage with players while expanding this into a complete multi-level adventure, starting with the goblin&#8217;s parents being hacked down by a merciless bunch of greedy adventurers, and ending with an unexpected and heart-wrenching moral dilemma. Or something.</p>
<p>We&#8217;re also planning on releasing the map editor as a core part of the game, and on making an on-line repository for player-made levels. There&#8217;s plenty of creative freedom in the map editor I have been creating, including customising the skills and chat text of the adventurers.</p>
<p><img src='http://i.imgur.com/OpQTiC0.gif'></p>
<p>You can sign up as a tester over at <a href="http://goblinsandgrottos.com/" target="_blank">goblinsandgrottos.com</a>, or <a href="https://www.facebook.com/goblinsandgrottos" target="_blank">follow us on Facebook</a>. A playable demo should be available within the next few weeks.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2015/introducing-goblins-grottos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Hittin&#8217; Worlds&#8221; Game Jam Winner</title>
		<link>https://www.psychicsoftware.com/2014/hittin-worlds-game-jam-winner/</link>
		<comments>https://www.psychicsoftware.com/2014/hittin-worlds-game-jam-winner/#comments</comments>
		<pubDate>Mon, 01 Dec 2014 10:39:13 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Conferences & Events]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=747</guid>
		<description><![CDATA[I took part in a game jam on Saturday, and we won! My main collaborator was artist Niall O&#8217;Reilly from local game art company DoomCube. The game runs using HTML5/Canvas, with a node.js websockets server. The &#8216;render client&#8217; ran on my laptop and players ran the &#8216;controller client&#8217; on their phones.. this seems like a [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I took part in a game jam on Saturday, and we won!  <img src="https://www.psychicsoftware.com/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" />  My main collaborator was artist Niall O&#8217;Reilly from local game art company <a title="Doom Cube" href="http://www.doomcube.com/">DoomCube</a>.</p>
<p><img class="aligncenter" title="Hittin' Worlds" src="http://www.psychicsoftware.com/hittinworlds2.jpg" alt="" width="616" height="491" /></p>
<p>The game runs using HTML5/Canvas, with a node.js websockets server. The &#8216;render client&#8217; ran on my laptop and players ran the &#8216;controller client&#8217; on their phones.. this seems like a really nice way to do casual LAN-style multiplayer games, and it&#8217;s a configuration I have been thinking about for a few weeks. I just need to figure out a killer party game idea to use it with!</p>
<p>In &#8220;Hittin&#8217; Worlds&#8221; Each player plays as a planet, in orbit around a sun. Asteroids are flying about, and players have to use their forcefield to deflect them. By using a virtual joystick-style controller on their phone, they orient the forcefield in specific directions.. incoming asteroids get deflected in that direction. The idea is that players fling the rocks at each other while defending themselves.</p>
<p><img class="aligncenter" title="Hittin' Worlds" src="http://www.psychicsoftware.com/hittinworlds-sml.jpg" alt="" width="600" height="338" /></p>
<p>We also had a really nice piece of custom music written by a guy called Ian, from Athlone/Reading.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2014/hittin-worlds-game-jam-winner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Raycast Car</title>
		<link>https://www.psychicsoftware.com/2014/raycast-car/</link>
		<comments>https://www.psychicsoftware.com/2014/raycast-car/#comments</comments>
		<pubDate>Thu, 09 Jan 2014 20:48:37 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Darkwind]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=686</guid>
		<description><![CDATA[Here&#8217;s some footage of a car driving around in the Shiva game engine, using the &#8216;raycast wheels&#8217; approach. I have found that this gives much nicer results than the demo car that comes with Shiva, which treats wheels as constrained spheres. The problem with modelling wheels as spheres rotating on one axis is that this [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s some footage of a car driving around in the <a href="http://www.shivaengine.com/">Shiva game engine</a>, using the &#8216;raycast wheels&#8217; approach. I have found that this gives much nicer results than the demo car that comes with Shiva, which treats wheels as constrained spheres. The problem with modelling wheels as spheres rotating on one axis is that this assumes rigid bodies for the wheels; actually, wheels are not rigid. </p>
<p>The basic idea with raycast cars is that you cast a ray from each wheel hub, and calculate the distance at which a surface is met (if at all). This defines the suspension&#8217;s extension, and then you simulate spring behaviour by applying increasingly strong forces as the suspension gets more compressed. There&#8217;s also some subtleties such as anti-roll and varying spring strength depending on whether its compressing or extending; but these are mostly tweaks applied to the core idea.</p>
<p><iframe width="600" height="450" src="//www.youtube.com/embed/pZY9Z3Dp698" frameborder="0" allowfullscreen></iframe></p>
<p>I also found that at high speed the default Shiva &#8216;spherical wheels&#8217; car would suffer from occasional glitches and speed wobbles, rendering it fairly useless for most games. Sometimes it seemed to stagger sideways at high speed, presumably due to errors on the axis constraints allowing the spheres to role sideways. I assume these problems are caused by over-relying on the accuracy of the underlying physical simulation in order to obtain the required behaviour. </p>
<p>In the video clips shown here, the behaviour of the car in all ways other than spring response has been results-driven, i.e. the desired behaviour (skidding, drifting, tendency to roll, etc.) has been considered and this is used as a starting point for programming the calculations &#8211; rather than starting from an accurate physical simulation and expecting realistic/fun results as an emergent behaviour.</p>
<p><iframe width="600" height="450" src="//www.youtube.com/embed/OBDp9v-To1g" frameborder="0" allowfullscreen></iframe></p>
<p>This represents very good progress towards what I&#8217;d like to have for a major new <a href="http://www.dark-wind.com">Darkwind</a> project (Darkwind 2?) that I have started thinking about. Really the ineffective default Shiva car is what had stopped me considering this before now.</p>
<p>Last year I also wrote <a href="http://www.musclecar-online.com">Musclecar Online</a>. In this the car was entirely results-based, having no accurate underlying physical simulation from which the behaviour emerged. Musclecar Online is actually a 2D driving simulation with 3D models (hence, no hills or bridges) &#8211; and it was therefore entirely possible to define the behaviour I wanted first and then to write code to directly produce that behaviour.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2014/raycast-car/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making an efficient gameserver with node.js and mysql (Musclecar Online)</title>
		<link>https://www.psychicsoftware.com/2013/making-an-efficient-gameserver-with-node-js-and-mysql-musclecar-online/</link>
		<comments>https://www.psychicsoftware.com/2013/making-an-efficient-gameserver-with-node-js-and-mysql-musclecar-online/#comments</comments>
		<pubDate>Mon, 29 Apr 2013 10:58:52 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Musclecar Online]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=547</guid>
		<description><![CDATA[Last year, when one of my games went a bit viral, I discovered first-hand about the alarming inefficiency of Apache (webserver), especially when running PHP which forces you to accept a process-per-request approach. It became pretty clear that something much more lightweight would be required if I wanted to build gameservers with large player-bases in [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Last year, <a href="http://www.psychicsoftware.com/2012/dont-launch-a-ddos-on-your-own-website/">when one of my games went a bit viral</a>, I discovered first-hand about the alarming inefficiency of Apache (webserver), especially when running PHP which forces you to accept a process-per-request approach. It became pretty clear that something much more lightweight would be required if I wanted to build gameservers with large player-bases in mind.</p>
<p>After some research I have settled on <a href="http://nodejs.org/">node.js</a> as a good solution. It&#8217;s very well regarded, largely due to its non-blocking, asynchronous model. This essentially means that anytime a resource is required (such as a database recordset) the request goes into a queue, to be called back when the resource is retrieved. In Apache, the model is blocking &#8211; the process sits and waits for the resource, thereby stopping any other activity.. this is why Apache needs all those independent processes, so that it can serve multiple clients simultaneously.</p>
<p><img style="float:right; padding:5px;" src="http://www.dark-wind.com/images/avatars/speed-racer2.gif" alt="speedracer" /> The game I have been working on is &#8216;Musclecar Online&#8217; &#8211; a top-down racer in which players build their own tracks, vote on them, and then everyone in the world races on the same track-of-the-day. Rather than being real-time, you race against the &#8216;ghost lap&#8217; recordings of other players; kinda like Speed Racer <img src="https://www.psychicsoftware.com/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" /></p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/nl3g4QCLZ_o" frameborder="0" allowfullscreen></iframe></p>
<p><strong>Cache stuff in RAM</strong></p>
<p>Linux has a server&#8217;s approach to the file system, of course, which means it uses all available RAM for caching disk files and such, but I figured it would be even better to make liberal use of Javascript arrays (which are really hash tables.. excellent for key-based lookups). So the server packs up canned responses into strings, as much as possible, ready for delivering over the interweb with no fuss or processing. This includes:</p>
<ul>a 5-day pack of track layouts, allowing the players to see what&#8217;s coming up over the next few days;</ul>
<ul>per-cartype, per-second frequency bins, succinctly providing the data needed by the client to display a histogram of worldwide laptimes and point out where the player stands versus these;</ul>
<ul>a temporary array of ghost lap recordings, hashed by user ID for easy over-writing when they improve. This is only used up until 40 players have recorded laps for that car type on that day&#8217;s track, and allows random &#8216;unclassified&#8217; packs of ghost laps to be delivered to players without the need to bother MySql about it;</ul>
<ul>more long-term packs of ghost lap recordings, separated into 6 divisions (F thru A) &#8211; the idea is that the player starts off racing against poor ghosts, labelled as division F, and if they beat these they are allowed to progress to division E, and so on. These longer-term packs are re-generated periodically, but not for the first time until 40 recordings are available for the car type.</ul>
<p><strong>Don&#8217;t fall into the ORDER BY RAND() trap</strong></p>
<p>I have done some pretty naive stuff in MySql in the past, but running <a href="http://www.dark-wind.com/">Darkwind </a>for the past 7 years has helped me understand efficient database design and querying. With the characters, vehicles and weapons tables running into the millions, I was forced to. One of the newbie gotchas in MySql is to avoid doing a massive SELECT statement with ORDER BY RAND() LIMIT 1 in order to get a random record. If you do this, you&#8217;re basically asking the database server to load an entire table into memory, apply a random number to each record, sort the whole damn thing, and return one row. There&#8217;s a few obvious solutions, depending on how well distributed the data in your index fields is. One simple way is just to find your data range (e.g. laptimes min and max), generate a random number in this range, and then SELECT the first row greater than or equal to this laptime, LIMIT 1. Assuming laptimes is an index field, and also assuming there are enough records to make a reasonably even distribution across the data range, this works nicely.</p>
<p><strong>Interesting asynchronous design solutions</strong></p>
<p>Now, I love callbacks as much as the next man, but it can be an old-fashioned PITA sometimes trying to work with asynchronous coding. In a nutshell, anytime you want a resource that may be delayed (database query, file read etc.) you can&#8217;t use a traditional flow of control, can&#8217;t use loops for multiple accesses, etc. One of the things I have to do in the &#8216;Musclecar Online&#8217; server is build packs of typical ghost lap recordings, in order to pack them into strings ready for dispatch to the clients. This means querying for each row with a separate SELECT statement, and therefore means 11 car types x 6 divisions x 5 different packs x 4 ghosts per pack =  1320 queries. Embedding each query inside the callback of the previous one certainly isn&#8217;t an option, but with a little thought I settled on recursion; a perfect way to unravel the asynchronous tangle. This works nice and efficiently, while still operating in serial (and therefore not choking up any server resources) and allowing nice tidy code. It&#8217;s kind of strange I didn&#8217;t see recursion mentioned as a solution anywhere on the web while researching node.js. Well, maybe I didn&#8217;t look for too long.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2013/making-an-efficient-gameserver-with-node-js-and-mysql-musclecar-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GUI Texture Atlases in Shiva</title>
		<link>https://www.psychicsoftware.com/2012/gui-texture-atlases-in-shiva/</link>
		<comments>https://www.psychicsoftware.com/2012/gui-texture-atlases-in-shiva/#comments</comments>
		<pubDate>Wed, 22 Aug 2012 11:41:29 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Dead By Dawn]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=456</guid>
		<description><![CDATA[As you probably know, it&#8217;s important to use Texture Atlases for efficiency reasons on mobile devices. The idea is that you pack lots of textures into one big one, and then use UV offsets to define which region of this large texture to display in your HUD components. This means that only one texture has [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>As you probably know, it&#8217;s important to use Texture Atlases for efficiency reasons on mobile devices. The idea is that you pack lots of textures into one big one, and then use UV offsets to define which region of this large texture to display in your HUD components. This means that only one texture has to be referenced by the graphics hardware. But it can be a bit fiddly calculating the UVs, especially if you want to add new textures to it later.</p>
<p>I have put together a nice workflow for this, so I thought it might be useful for other people too..</p>
<p><strong>Step 1:</strong> Create your texture atlas. I use a program called <a href="http://www.codeandweb.com/texturepacker">Texture Packer</a> for this, which combines your textures into a single PNG and also exports an XML description of it (which we&#8217;ll need later; we could of course manually write the XML but it&#8217;s a bit more work that way..)</p>
<p><img src="http://www.psychicsoftware.com/images/texture-atlas-1.jpg" alt="Texture Packer" /></p>
<p><strong>Step 2:</strong> Write or export your XML. My Shiva code a bit later will assume the following format, which is what Texture Packer gives us. It simply encodes the names of the images (sprites), along with their positions and sizes in the atlas.</p>
<p><code>&lt;TextureAtlas imagePath="ZS_icons.png" width="512" height="512"&gt;<br />
&lt;sprite n="backpack" x="204" y="2" w="160" h="186"/&gt;<br />
&lt;sprite n="rotate_left" x="366" y="51" w="48" h="47"/&gt;<br />
&lt;sprite n="rotate_right" x="416" y="2" w="48" h="47"/&gt;<br />
&lt;sprite n="search" x="366" y="2" w="48" h="47"/&gt;<br />
&lt;sprite n="shotgun" x="2" y="2" w="200" h="86"/&gt;<br />
&lt;/TextureAtlas&gt;</code><br />
<strong><br />
Step 3: </strong>Import the xml file and texture atlas in to Shiva</p>
<p><strong>Step 4:</strong> Create your HUD. Anywhere you want a texture out of the atlas, just set that HUD component to the Atlas texture (it looks a bit weird at design-time..)</p>
<p><img src="http://www.psychicsoftware.com/images/texture-atlas-2.jpg" alt="HUD at design time" /></p>
<p><strong>Step 5: </strong>Add an XML variable to an AI, and set it initialised from the imported xml. (I call my xml variable <strong>xmlZS_icons</strong>, and hard-code that in the code below)</p>
<p><strong>Step 6: </strong>Add the following function to your AI:</p>
<p><code>--------------------------------------------------------------------------------<br />
function MyAI.SetUvsFromTextureAtlas ( sComp,sIcon )<br />
--------------------------------------------------------------------------------</code></p>
<p><code>local r = xml.getRootElement ( this.xmlZS_icons ( ) )</code></p>
<p><code>local imgWid = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( r, "width" ) ) )<br />
local imgHgt = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( r, "height" ) ) )</code></p>
<p><code>local c = xml.getElementChildCount ( r )</code></p>
<p><code>for i=0, c-1 do</code></p>
<p style="padding-left: 30px;"><code><br />
local e = xml.getElementChildAt ( r,i )<br />
if ( sIcon==xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "n" ) ) ) then</code></p>
<p style="padding-left: 60px;"><code><br />
local uscale = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "w" ) ) ) / imgWid<br />
local vscale = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "h" ) ) ) / imgHgt<br />
local u = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "x" ) ) ) / imgWid<br />
local v = 1-( string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "y" ) ) ) / imgHgt )-vscale<br />
local comp = hud.getComponent ( application.getCurrentUser ( ),sComp )<br />
hud.setComponentBackgroundImageUVOffset ( comp, u, v )<br />
hud.setComponentBackgroundImageUVScale ( comp, uscale, vscale )<br />
return</code></p>
<p style="padding-left: 30px;"><code><br />
end</code></p>
<p><code>end</code></p>
<p><code> </code></p>
<p><code>log.message ( "Unable to find icon '"..sIcon.."' in texture atlas!" )</code></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p><code> </code></p>
<p>&nbsp;</p>
<p><code>--------------------------------------------------------------------------------<br />
end<br />
--------------------------------------------------------------------------------</code></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p><strong>Step 7: </strong>And finally, whenever you instantiate your HUD, call the following for each HUD component that&#8217;s included in the texture atlas:<br />
<code><br />
this.SetUvsFromTextureAtlas ( "MyHUD.MyComponent", "sprite_name" )</code></p>
<p>&nbsp;</p>
<p><img src="http://www.psychicsoftware.com/images/texture-atlas-3.jpg" alt="final result" /></p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2012/gui-texture-atlases-in-shiva/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shiva Undergrad Course</title>
		<link>https://www.psychicsoftware.com/2012/shiva-undergrad-course/</link>
		<comments>https://www.psychicsoftware.com/2012/shiva-undergrad-course/#comments</comments>
		<pubDate>Fri, 04 May 2012 13:50:44 +0000</pubDate>
		<dc:creator><![CDATA[sam]]></dc:creator>
				<category><![CDATA[Conferences & Events]]></category>
		<category><![CDATA[Techie]]></category>

		<guid isPermaLink="false">http://www.psychicsoftware.com/?p=300</guid>
		<description><![CDATA[This is the content from a complete 9-week undergrad course that I taught between January and April this year. I hope it&#8217;s useful to some other Shiva developers! WEEK 1 &#8211; intro, IDE, API overview Lecture 1 &#8211; Introduction Lab 1 &#8211; Setup Shiva + Mars Rotator Mars model (Collada .dae and .jpg) (for use [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>This is the content from a complete 9-week undergrad course that I taught between January and April this year. I hope it&#8217;s useful to some other Shiva developers! </p>
<p><strong>WEEK 1</strong> &#8211; intro, IDE, API overview<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week01.Intro.pdf" target="_blank">Lecture 1 &#8211; Introduction</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/lab1.pdf" target="_blank">Lab 1 &#8211; Setup Shiva + Mars Rotator</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/marsmodel.zip" target="_blank">Mars model (Collada .dae and .jpg)</a> (for use in lab session 1)</p>
<p><strong>WEEK 2</strong> &#8211; key game entities, automatic flow of control, AIs, keyboard, accelerometer<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week02-03.pdf" target="_blank">Lectures 2&amp;3 &#8211; Concepts, the Shiva SDK etc.</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/lab2.pdf" target="_blank">Lab 2 &#8211; Mars and its moons!</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/week2assets.zip" target="_blank">Phobos/Deimos models (Collada .dae and .jpg) and skyboxes (.jpg)</a> (for use in lab session 2)</p>
<p><strong>WEEK 3</strong> &#8211; programmed flow of control, messages, key game entities, data handling<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week02-03_v2.pdf" target="_blank">Lectures 2&amp;3 &#8211; Added to since last week!</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/lab3.pdf" target="_blank">Lab 3 &#8211; Mars with collidable asteroids</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/asteroid.zip" target="_blank">Asteroid model (Collada .dae and .jpg)</a> (for use in lab session 3)</p>
<p><strong>WEEK 4</strong> &#8211; physics, direct movement, the camera<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week04.pdf" target="_blank">Lecture 4 &#8211; physics, movement, camera</a><br />
Labwork: start on your game projects; complete lab 3 if you haven&#8217;t done so yet.</p>
<p><strong>WEEK 5</strong> &#8211; HUDs, runtime object management, coordinate systems, vectors and angles, ray casting, the math object<br />
<a href="http://www.psychicsoftware.com/ct249.2/lab3_solution.pdf" target="_blank">Sample solution to lab 3 (Mars with Moons and Asteroids)</a><br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week05.pdf" target="_blank">Lecture 5 &#8211; HUDs, raycasting, runtime object management</a></p>
<p><strong>WEEK 6</strong> &#8211; sensors &amp; colliders, tables, hash tables, xml, game deployment<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week06.pdf" target="_blank">Lecture 6 notes</a></p>
<p><strong>WEEK 7/8</strong> &#8211; particle emitters, multiplayer, multitouch, efficiency, Shiva script and OpenGLES, materials &amp; lighting, pathfinding<br />
<a href="http://www.psychicsoftware.com/ct249.2/CT249.2.Week07.pdf" target="_blank">Lecture 7/8 notes</a></p>
<p><strong>Demo Games that we will be discussing in class:</strong><br />
<em>The Shiva webplayer plugin will automatically install.. </em><br />
<a href="http://www.psychicsoftware.com/afterburn2150/AfterburnWebPlayer.html" target="_blank">[Afterburn 2150]</a><br />
<a href="http://www.psychicsoftware.com/demo/marsdefenderdemo.html" target="_blank">[Mars Defender]</a><br />
<a href="http://www.psychicsoftware.com/demo/blockrockindemo.html" target="_blank">[Block Rockin]</a></p>
]]></content:encoded>
			<wfw:commentRss>https://www.psychicsoftware.com/2012/shiva-undergrad-course/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>


<!-- Begin Cookie Consent plugin by Silktide - http://silktide.com/cookieconsent -->
<script type="text/javascript">
    window.cookieconsent_options = {"message":"This website uses cookies to ensure you get the best experience","dismiss":"Got it!","learnMore":"More info","link":"http://www.psychicsoftware.com/privacy-policy/","theme":"dark-bottom"};
</script>

<script type="text/javascript" src="//s3.amazonaws.com/cc.silktide.com/cookieconsent.latest.min.js"></script>
<!-- End Cookie Consent plugin -->

