wickedworx

March 14, 2011

THIS BLOG IS MOVING

Filed under: Uncategorized — wickedworx dev clone 1 @ 4:25 pm

I have moved this blog to http://blog.wickedworx.net … it’s a whole “new” blog (although I have migrated all the old content from here, to there..). Give it an hour or so, if you are impatient… Party on!

Advertisements

February 7, 2011

A simple scripting system (as used by EGV)

Filed under: Technical — wickedworx dev clone 1 @ 6:40 pm

Summary

Excruciating Guitar Voyage was a game driven by content, as a lot of adventure games are. A key component in the arsenal of any content/story driven game developer is the ability to script game and world events.

A lot of developers, when talking about scripting, will think of LUA, JavaScript and AngelScript. But it is worth me saying – these may be “scripting languages”, but that doesn’t mean they are necessarily the right tool for the task of scripting events in your game.

For EGV, we wanted a scripting system which was higher level than what a pre-existing scripting language would provide.. a system which gave us direct control of the game. Another key element was that we wanted to be able to switch between a script ‘blocking’ the operation of the main game, and a script running alongside the main game per command… but I’ll get on to that later.

WELCOME TO: “EGV’S MEGA SIMPLE, EXTENDABLE, FLEXIBLE SCRIPTING SYSTEM PART 1”


This example is all in C#. I have implemented this exact same system in C++ on previous occasions…so, uh, write it in whatever language you want – the concept is the same.

Our requirements for this system:

  • High level – to the point it is almost ‘game specific’, and that game specific commands can be added
  • Mixed blocking/passing (similar to ‘mixed asynchronous’) behaviour
  • Simple and quick to use, reasonable to debug
  • Fast to parse (we pre-cache all potential scripts on level load)
  • Not exclusively for cutscenes – player doesn’t have to stop playing while scripts are running
  • Conditions, and branching (“if” support) would be ideal*

OK – so a few assumptions of the game:

  • All important game objects have a “tag” name.
  • There is a “GameResource” which contains a reference to pretty much any game system we may need
  • Game Objects in EGV use a component system. This shifts behaviours in to separate components, making it ideal for this kind of scripting.

* Branching/conditionals to be covered in next post.. we’ve already got it implemented, but I’ve taken it out from this code to avoid too much early bloat in the tutorial. Next post will go about adding it back in!

Implementation

Our scripting system consists of 3 main classes:

  • ScriptManager – holds a list of all currently running scripts, updates as necessary
  • Script – a script. holds a list of all the commands it must run, updates as necessary
  • IScriptItem – class off which script commands can inherit

class ScriptManager    
{        
    GameResource m_gameResource;        
    List<Script> m_runningScripts = new List<Script>();        
    List<Script> m_toAdd = new List<Script>();

Notice I’ve got two lists: “Running Scripts” and “To Add”. The second list is there in case one of our scripts launches another scripts while running – it means we can get around modifying the “Running Scripts” list while it is being iterated through. Each frame, scripts from the “To Add” list are copied to the “Running Scripts” list, and the “To Add” list is subsequently cleared.

See ScriptManager here http://pastebin.com/hg3nBMR0

So, the idea is:

  1. Event happens in game, causes a script to be loaded
  2. ScriptManager creates a new script, using the data from the .xml file
  3. Script reads data from xml file and creates an IScriptItem for each command* within it
  4. The Script now contains a list of IScriptItems and has a “current index” variable which stores which script command it is currently running
  5. Next frame, ScriptManager calls update on the new script
  6. Script calls ‘run’ on the first IScriptItem in the list. If/when this command is finished, it moves on to the next command.

Behaviour

So, there are two different situations which we have to take in to account:

  • Situation A) We want to run a number of script commands all in one frame. e.g. we want to remove the banana object, add an explosion there, play an explosion sound, spawn some particles. This all has to be done in one frame – if this were spread out over four frames (e.g. one frame per command) – it would look ridiculous.
  • Situation B) We want one script command to keep running for a number of frames. e.g. we want to wait 2 seconds between blowing up the bin and a character commenting on the fact the banana has exploded.

This is the interface which I came up with to solve these two situations:

public virtual void run(float dt) {}        
public virtual bool shouldUpdateGame() { return false; }        
public virtual bool isComplete() { return true; }

Note, I decided against a “pure” interface and have opted to add ‘defaults’ to the functions “shouldUpdateGame” and “isComplete”, as the majority of script commands will end immediately and not need a game update.

So here’s the idea in bullet-point go-to logic:

  • point A) Game is updating. Game updates  full frame, then updates ScriptManager.
  • point B) Script Manager runs, updates script, RUN is called on the current ScriptItem (using our index!)
  • shouldUpdateGame() is called and the result stored
  • isComplete() is called. If this returns true then the current ScriptItem index is increased
  • if the result stored from shouldUpdateGame is ‘true’, we’re back to “point A”.. if it is false, don’t update the game – essentially carry on from “point B” without letting another frame pass — UNLESS this script has entirely finished, in which case, we’re done anyway!

Here’s the logic for that:

public bool run(float dt)     //   Script.run(float dt)
{            
    bool shouldBreak = false;            
    while ( true )	        
    {		        
        if ( m_itemIndex >= (int)m_items.Count )		        
        {			        
            return false;	// return false - this script is finished	        
        }		        
        if ( shouldBreak )		        
        {			        
            return true;        // return true - let game carry on, but this script has more to do next frame
        }
                               // Continue on - run the next item        
        m_items[m_itemIndex].run(dt);		        
        shouldBreak = m_items[m_itemIndex].shouldUpdateGame();		        
        if ( m_items[m_itemIndex].isComplete() )		        
        {			        
            ++m_itemIndex;		        
        }
    }        
}

Loading

So, now we have the logic to run a linear script – we just need a few implementations of commands and a way to build a script!

The format of one of our scripts is as follows:

<script>
<command_name parameter1=”example parameteranother_parameter=”10” />
</script>

In our framework, across all our systems we have a unified XML load system. This converts XML (like above) to a tree of DataNodes. DataNodes have a name, an optional value and an optional list of child nodes.
In the above example, we’d end up with a DataNode with a name “script”, with a child DataNode (named “command_name”), with two child DataNodes (named “parameter1” and “another_parameter”), which have values of “example parameter” and “10” respectively.

Let’s add a couple more functions to our IScriptItem:

class IScriptItem    
{        
    GameResource m_gameResource;        
    public virtual void run(float dt) {}        
    public virtual bool shouldUpdateGame() { return false; }        
    public virtual bool isComplete() { return true; }        
    protected GameResource getGameResource()        // protected, access to GameResource
    {            
        return m_gameResource;        
    }        
    public void baseSetup(GameResource gr)        // set up base (don't rely on ScriptItem implementations to remember this)
    {            
        m_gameResource = gr;        
    }        
    public virtual void setup(DataNode node)        // set up function for overriding - passed a DataNode
    {
    }    
}

I decided to keep the name “IScriptItem” despite it not being a pure interface.

A Script is constructed from an xml file, which is converted to a DataNode. It then constructs all its script commands using the list of children in it’s DataNode. Each command in the script is build from a DataNode (and its children)

class Script    
{        
    List<IScriptItem> m_items = new List<IScriptItem>();        
    GameResource m_gameResource;        
    int m_itemIndex;        
    String m_filename;        
    bool m_shouldDelete = false;

    public Script(String filename, GameResource resource)
    {            
        m_filename = filename;            
        m_gameResource = resource;            
        DataNode rootNode = DataNodeResource.getDataNode(@"Content\scripts\" + filename);            
        m_itemIndex = 0;            
        addFromNode(rootNode);            
    }
    void addFromNode(DataNode node)        
    {            
        int nodeCount = node.getNodeCount();            
        for (int nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex)            
        {                
            DataNode thisNode = node.getNode(nodeIndex);                
            String itemType = thisNode.getName();
...

So, here we are iterating through command nodes, and getting a string from each – “itemType”. Using this itemType we can determine which class (inheriting from IScriptItem) to create an instance of. In our current code, we use Generics and a Registered Builder pattern to avoid a huge series of “if-else”.. but for this example, it’s probably easier to go down the “if-else” route! (There’s enough examples of using Generics to build objects from Strings in C# on the internet already!)

...
            IScriptItem itemToAdd = null;
            if ( itemType == "wait" ) // replace these else-ifs with your favourite String -> Object building logic
            {
                itemToAdd = new ScriptItems.Wait();
            }
            else if ( itemType == "play_cue" )
            {
                itemToAdd = new ScriptItems.PlayCue();
            }

            if (itemToAdd != null)
            {
                itemToAdd.baseSetup(m_gameResource);   // set up base
                itemToAdd.setup(thisNode); // pass data to item set up
                m_items.Add(itemToAdd);
            }
            else 
            {
// throw an exception or do some error thing here - you've tried to use a command in your script which doesn't exist!
            }

Full Script class here http://pastebin.com/DbX9SGUz

Command Logic

The great thing is – every time we want to add a new command, we just add a new class inheriting from
IScriptItem. EGV has about 30 commands, some of them very specific (“walk_to” and “speak”), and some of them more generic (“spawn_object”, “remove_object”, “set_animation”).
Adding new commands doesn’t seem to happen very often, and when it does – it’s usually a fairly quick addition…most of our commands involve finding a GameObject in the world, and calling a function on them.**

So, that should deal with adding two types of item – a “wait” and a “play_cue”. How do these look?

Wait

Class

class Wait        :        
IScriptItem    
{        
    float m_delay;        
    public override void setup(DataNode node)        
    {  
        // read in the delay required         
        m_delay = node.getNode("time").getValueF();        
    }        
    public override bool isComplete()        
    {            
        // this command isn't finished until the delay is over
        if (m_delay < 0)            
        {                
            return true;            
        }            
        return false;        
    }        
    public override bool shouldUpdateGame()        
    {            
        // we only want the *script* to wait, the rest of the game should carry on in the mean time
        return true;        
    }        
    public override void run(float dt)        
    {            
        m_delay -= dt;        
    }    
}

In Script

<wait time="5" />

This will cause a pause of 5 seconds in the script, while the game continues. Very useful in a script!

Play cue

Class

class PlayCue        
:        
IScriptItem    
{        
String m_cue;        
    public override void setup(DataNode n)        
    {            
        m_cue = n.getNode("cue").getValue();        
    }        
    public override void run(float dt)        
    {            
        getGameResource().getAudioManager().playAndDispose(m_cue);        
    }    
}

In Script

<play_cue cue="fx_explode" />

End of side 1

Well, there you have it – a simple linear scripting system – great for cutscenes. It’s a 5 minute job to add a new IScriptItem – so if you want a command to kick off an animation, set the camera’s target position, tell a character to walk to a new location, wait for a character to finish walking to their target location.

The majority of ‘acting’ logic still must be in your game objects (e.g. your script may command your character to walk to “location X”, but it is the character’s update which is responsible for actually walking him there). Using our component system, we have a component “ai_walk” which is responsible for this behaviour. If you command an object to walk, which doesn’t contain an “ai_walk” component – it simply won’t go anywhere…

Here are a few example script commands we use:

  • Spawn Object
  • Remove Object
  • Walk To (character walking)
  • Add Focal Point (camera)
  • Remove Focal Point (camera)
  • Add Objective (for player’s objective list)
  • Remove Objective
  • Speak (character talking)
  • Wait for talk (wait for a character to stop talking)

So, even this small set of commands, it is possible to see how a cutscene with a couple of characters talking / walking to a new location can be easily created.. (and object being added or removed, the player’s objectives being updated etc..)

In the next blog on this subject, I’ll write about how we implemented branching (IFs, etc..), variables and conditions.. transform this linear system can be transformed in to a full script language that can be used for more than just cutscenes.

**While on the train today, I had some thoughts about how this system could be made more “OO”, and more cohesive with our existing GameComponent/Message system… so maybe I’ll write a post about that (and why I don’t think we’ll be switching to it immediately) some time!


February 1, 2011

post ‘world of love’ update

Filed under: Uncategorized — wickedworx dev clone 1 @ 12:41 pm

Friday was the World Of Love independent games development conference, in London. I went along not really knowing much about any of the individual speakers or companies involved…but I guess that was half the point, right?

There were some interesting talks (the highlight, for me at least, being a talk by the creator of “Dark Wind“, a one-man created mmo. very impressive, and stand-out. Some of the other talks were more along the lines of “this is our company, and this is how we work” – which, for me, is less interesting…especially when these companies tend to act more as an outsource for IP-owning clients, rather than really developing independent projects. – not really so much the side of things that I’m interested in, personally.. although there are some areas of cross-over, I’m sure.
All in all a very good day, met some genuinely enthusiastic indie devs (and non-devs) and had 3 cups of tea. Also had this cake which was really good.
So is there a place for content driven independent games? Uh.. well, I guess we’ve still got that to answer. And I guess the main thing that stuck with me from the day is: “How do you describe Excruciating Guitar Voyage (series) in one sentence?”. That’s something that’s got to be thought about.

(SIDENOTE: EGV1 is now popular enough that it has been pirated, by some pirate group. thanks a lot, you dicks!)

The next morning, we went along to the post-WoL game-jam (we being myself, Joakim and Ben)..we’d had about 2 hours sleep after a particularly tiring evening/night/morning in Islington, and it was showing.. we created a small game, which I’m currently calling “Tortune”.. it’s a spinning disc rhythm game with poly-rhythms and awkward sounds.. it was pretty much a manifestation of our exhaustion, in game form.. we made a 2 player mode which was way more fun, but then we added some animals textured with train seat textures – and you couldn’t see them that well with 2 players – so it was back to 1 player… It was great to hang out with some other devs and see some of their work… and, uh, apologies we were such a state!

Monday – back to EGV2. The “isolated puzzle area” I’ve been working on is all coming together well.. it’s actually gotten to be quite large.. hopefully not too large. It’s got ghosts, gingerbread, and bookcases.. it’s all a little spooky!
Got some awesome new assets from Tim. EGV2 is going to look great. A few people played a section of it over the weekend – which has led me to think it needs a little difficulty balancing… we hadn’t done any real testing (of any kind) with EGV2 previously, so it was nice to see a few reactions. The intro and new animations seemed to impress, so that’s GOOD NEWS.

Stick Unleashed went back in to peer review yesterday…. We got loads a bit of Kieronononon recording done – some of which will almost definitely end up as part of the EGV2 soundtrack. So, yeah, I’ve been busy.

well, that’s my blogbligation complete for this week. BYE. fucking screenshots next time, yeh?

(oh yeah, PX has new legs:
)

January 22, 2011

EGV2 updates

Filed under: Uncategorized — wickedworx dev clone 1 @ 11:54 am

the past week I’ve been back on the EGV2 path. The first major update is that Tim has given PX a new body:
PX new body
He looks like a real person! The 7-sided blob body is gone… forever.

I’ve been working on one of the ‘set piece’ levels. It’s going pretty well so far – we’ve got those nice dynamic shadows, moving staircases, gingerbread men, and a whole load more.. I’m about to put some heavy machinery in and actually start shaping the puzzles… it’s a fairly isolated area in some respects, so it doesn’t have to rely on, or have any major implications on other areas of the game….which is good for design freedom here.

The preview build is still coming along… we’re planning that it’ll showcase the first 5-10 minutes of the game, our new graphics and new interface.. it’s not too puzzle heavy or difficult, as it’s the very first section of the game.

Not much else to report on..everything progressing fairly solidly. Oh – We’ve also got the new “objectives and inventory” screen in.. it’s much less intrusive than previously.. More soon!

January 11, 2011

Stick ‘Em Up: Even More Stick

Filed under: Uncategorized — wickedworx dev clone 1 @ 4:21 pm

I’ve been working on a follow-up to 2010’s “Stick ‘Em Up”.. It’s called “Stick ‘Em Up: Even More Stick”.

One of the key features of SEU:MS is the new level editor! You can now build your own VS levels, co-op levels, or even just “stick man playgrounds” right within the game on X360.

I’ve made a video of me creating a level from scratch here:

There were several challenges in creating the level editor. Firstly, I had to occlude any lines which should not show, where geometry overlaps. In our own levels, we can always control where geometry overlaps – so we’d just not put in any of these lines… but I can’t stop a player from doing this – so I’ve had to use some stencil buffering to make it render multiple objects which overlap, as if they are one solid block.

I’ve had to make some optimizations to the SEU framework/engine in general to speed things up – it’s highly likely that a player will create rooms packed with more enemies than a normal SEU level.. I’ve had to put some limits on how many enemies can be placed in the level (for memory and performance), but I’ve also optimized all the AI and object spawning to make sure that things run as smoothly as possible even when at these limits.

One fun thing is that I’ve included all the vehicles in the editor.. so you can just create a set of ramps and obstacles for the car, should you wish… or just add a whole load of invaders (and invader ships for the players) and make essentially a twin-stick space level!

December 17, 2010

a look at WickedWorx tools, December 2010 edition

Filed under: Technical — wickedworx dev clone 1 @ 12:35 pm

COMPONENTIATOR
the “plus” symbols you see everywhere show positions of objects (whether they are just nodes for camera work, guiding walk paths in scripts, spawning objects at a position later etc.., or actual physical world objects.. sprites, decals, characters, etc.. some are lights!)
they’re all at funny angles so that if two are in the same place – you can see both!! 😉

the top right box shows the list of objects in the scene.. the 2nd box down shows the components the current object is made of, and the 3rd box down lets you edit the parameters sent to that component on create.

there’s also a slider for zoom which i shoved in the middle ‘coz it didn’t seem to fit anywhere else.

the initial version of this editor was probably put together in around 3-4 hours… it’s had a few improvements since (one which Kevin is particularly proud of is the “clone” button, which we didn’t have during EGV1).. – still, it’s probably saved us 100s of hours, as previously we would be hand editing .scene files (me and Jon C did this during Whatever Games SEU1 – it was definitely stressful!).. so, in terms of an investment for time saving – pretty effective..
Componentiator is cross-project, too… SEU2 (Whatever Games), EGV1+2, Super Janitoroid… a few others are using it for their own games (Goatbuoy is working on a pinball game using our stuff, and has picked up Componentiator pretty quickly!…possibly finding us a few bugs to fix on the way…)

oh – and here’s a picture of our animation tool:
ANIMHATOR
characters in EGV are made up of floating parts which we move about to create nice animations.
for EGV1 we didn’t have an animation tool… we just hand edited all the .anim (xml) files.. this meant that some animations were more simplistic than if we could’ve had a visual editing tool… animations in EGV2 are more slick and detailed!
Should mention that Animhator isn’t quite as cross-project as Componentiator, as it really only animates in the style of EGV… although it could be used for sprite/frame based animation – there would probably be better ways of doing this.
Animhator still has a lot of bugs and quirks, but we’re gradually working them out… it also has a special area for rushed features. Great!

December 14, 2010

EGV2

Filed under: Uncategorized — wickedworx dev clone 1 @ 10:18 am

We’ve started work on EGV2. There’s no point keeping it secret. We’re working on EGV2 right now!

A few things have changed and improved since the first. We’re making a real effort to bring the characters and the whole EGV world to life… we’ve got better animation (including animated mouths!) which gives a lot more weight to the characters.. and we’ve made a few changes so the whole world feels a little less flat.

I started the week with the worryingly talented Daniel Gallagher (Dan Flashbang) recording some new material for the game… it worked out a lot better than we expected, especially given the time constraints we came up against on the night. We may have used a little too much time eating tacos (yes, really..) and watching “Hotel Inspector” (ugh), but we got the job finished by 11pm!

Then we’ve got this really great scene at the beginning of the game…. I don’t want to spoiler it yet, but I’ve been working on that.. There were a few technical challenges – we’ve got a far improved camera system, which has allowed us some really nice dynamic camera choreography for the intro scene… I’ve also written a pre-cache for our level geometry, which means we can do some neat dynamic effects mid-level.. instantly change the shape of whole buildings, etc.. with absolutely minimal overhead, as all the vertex buffers for the change have already been generated. A fairly obvious thing, in a way – but we hadn’t needed it in previous projects as level geometry had remained relatively static once created.. Not this time!

November 8, 2010

SUPER JANITOROID & more

Filed under: Uncategorized — wickedworx dev clone 1 @ 12:30 pm

Since EGV launched on both X360 and PC, I’ve been fairly busy (considering I was originally going to take a break for a week or two) working on a “spin-off” called SUPER JANITOROID.

In a lot of ways it was an exercise to see how flexible our current framework is at creating a different style of game.. We’ve got new animation tools, and improvements to our level editor – which have definitely helped with this new game… as well as a few speed improvements in loading / object creation.

The majority of programming for this game has been within components…which is a good sign! I’ve written a few components for enemy AI, for weapon types, and moving platforms.. the rest of this project has mainly just been level design, animation and similar content creation tasks! So – that’s been quite good in “proving” the framework.

EGV has done pretty well in comparison to our expectations.. it’s definitely a complex game to explain to someone, despite it really just being platform/adventure, there’s something else to it which might initially throw people… either way – the feedback from those who’ve played it has been brilliant..and that’s what we can hope for! party on! anyway – time for me to try and finish off SUPER JANITOROID.
TRAILER:

September 25, 2010

EGV in peer review!

Filed under: Uncategorized — wickedworx dev clone 1 @ 5:18 pm

We’ve put EGV in to peer review on X360! Let’s hope it gets through!!

September 8, 2010

Finished!

Filed under: Uncategorized — wickedworx dev clone 1 @ 9:15 pm

Excruciating Guitar Voyage is finished.
I’ve forgotten what I do with my time when I’m not working on it.
While I work that out, we’re busy packaging the game up, and looking at our options re: distribution (on PC, at least)… on X360, it’s easy – through the indie channel. PC is now the more difficult platform distribution wise..

Wow. Finished. It’s been amazing how the game has all fallen in to place. It’s so dramatically different from what it was one month ago, or even two months ago. We’re really really epically pleased with how its turned out, so here’s some screenshots… I’m not going to resize them to fit because I’ve done enough work for one day:





Older Posts »

Blog at WordPress.com.