Showing posts with label ideas. Show all posts
Showing posts with label ideas. Show all posts

Friday, 26 July 2013

Schedules

SymCity is meant to be a sandbox game that allows player to explore the world at their own pace. To add variations to the world, it has to evolve with the player's exploration. The most obvious choice of variation is to modify the world with events - and naturally scheduled events plays a fundamental role.

The concept of schedule event is simple:

Player's actions advances time, and at designated times, events will be triggered: locations become accessible; character moves to different location etc.

There're different ways of doing this depending on the scale of the game - you could have nested conditions setup in your game if it's fairly linear. I suspect a lot of story driven RAGS games with "day" counters use this approach, by defining specific times when certain events will be triggered.

For a sandbox game, this is just won't do.... So let's try something else. For my approach to this problem (credits to Anonymous's suggestion as well on TPoC blog earlier this year), we'll need:

Time_now - A time variable.

This is a Date Time variable, so we can do simple operations like "add minutes" or "add hours" to it. This is basically what day and time it is in the game world.

Schedule_List - A multi-dimensional array that keeps track of the schedule.

The MDA holds the scheduled time, threshold time, schedule pattern, timer name and variable name. The list is always kept in ascending order. More explanations later.

Active Timer: Schedule-Checker - Checks the Time_Now against Schedule_List

As the schedule list is in ascending order, this timer just does a while loop to see if the first "scheduled time" on the array is due for processing, if so, it calls the next timer:

Inactive Timer: Schedule-Trigger - Manipulates the Schedule_List array

This is where the magic happens. This timer checks the "threshold time" to see whether we still want to execute the associated event. This is due to the nature of some actions / events potentially taking up several hours - by which point we might not actually want to execute the event anymore.

If we want to execute the event - then we simply execute the timer by name stored in the array, and supply suitable variable to it.

Next we need to remove the top item from the Schedule_List array, because it's been expired (whether we triggered the event or not). But first we have to determine the next scheduled time and threshold time, using the schedule pattern.

Since this next part is purely to manipulate the array data, I do it by javascript. Read the schedule pattern, calculate the next scheduled time and threshold, push it to the end of the array, sort the array and return it. Now we have the next scheduled event on the top of our list!

RAGS Code below.

Timer Schedule-Checker:

Variable: Set (Javascript): aStr1, [true if Time_Now > Schedule_List(1)(0)] Loop: While: aStr1 Equals True Timer: Execute Timer: Schedule-Trigger Variable: Set (Javascript): aStr1, [true if Time_Now > Schedule_List(1)(0)]

Timer Schedule-Trigger:

Variable: Set (Javascript): aStr1, [true if Time_Now > Schedule_List(1)(1)] //passed threshold time yet? Variable: Comparison: aStr1 Equals False Variable: Set: TM_[v:Schedule_List(1)(8)], [v:Schedule_List(1)(9)] Timer: Execute Timer: [v:Schedule_List(1)(8)] Variable: Set (Javascript): Array: Schedule_List, [pop the first schedule, refill the schedule time if next available time exists, set threshold time, push back to array, sort and return]

Note 1: I actually cheat a little with my array by having titles on the first row, so rather than calling picking Schedule_List(0)(0) for the first scheduled time, I pick Schedule_List(1)(0) which is actually the second row.

Note 2: Rather than setting and retrieving Timer Custom Properties, I opted for using variable variables for quicker variables setting. All Timer's variables are named TM_[Timer Name]

I realised after writing this post that I should probably allow empty thresholds, and if threshold time is empty, then execute the event regardless. But hopefully this gives you some ideas of how to schedule events in your RAGS game.

I'm not releasing the code for this because the Javascript to calculate the next scheduled time is highly specific to SymCity's needs (I took some shortcuts) - so it's not a fully featured javascript function. If you're able to tweak it to your needs, you can probably code it from scratch (it's 2000 characters long); if you can't, then it's probably best you avoid it.

If you really want to play with scheduler but are not confident in coding the "next scheduled time" with javascript, you can always just build a list using actual time and skip the schedule pattern.

Hope this is of use to some of you guys :)

Saturday, 20 July 2013

A list of Ideas

So just to help me plan out my future posts, I'm putting down a list of ideas I'm currently working on or planning on experimenting with. If I get hit by a bus tomorrow, you guys are in charge!

Dynamic Rooms
Building your world with a simple array and some "On Leave" timers
What to do with the Compass
The compass sucks, we never knew what to do with it. In TPoC I decided to turn it into a mini-map of your current location. By let's take it further: how about a slightly larger map view (regional map) with a "you are here" dot?
Forget about locked doors
RAGs' door mechanics is a lot of work, unlock door (deactive unlock action), open door (check if it's locked or closed, change exit to active, deactivate open action), close door etc etc. Simplify this with "Enter" action which transports you to the next room if door's opened.
Scheduled events
Overlay stats
Since most of us don't want to do the time consuming and often awful looking photoshop cutouts just to allow overlaying of images, we rarely utilise it. Well we all know the status bar is too limiting, so why not overlay some key stats on the bottom of the main media screen? Research barometer, Notoriety rating, equipped items.

That's it for now, more to come later, hopefully.

Thursday, 18 July 2013

Dynamic Characters

Most of you would probably have played DollMistress's Overseer. It caters towards those with Latex, Living Doll and Bondage fetish in particular, that's 2 out of 3 for me. It's also an ambitious game to push the envelope in terms of what complex mechanism can be achieved.

I won't go in depth about all the game mechanics bar one today - the drones.

Overseer lets you entrall victims in your base or go out to hunt for some yourself, you put them through the slave chamber and they get turned into objects - literally.

I guess the programming reason to convert RAGs Characters into RAGs Objects is to separate the code between individual characters and individual drones. Rather than having the code for every possible drone type action coded into each character, DollMistress can create the drones separately from the characters you capture on the first place. A second good reason is probably because Objects are easier to copy and paste than Characters (seriously Steve, Characters and Rooms should be organisable like Objects and Images).

Anyway, I thought this was a genius idea and I'm definitely stealing it. But when thinking about how I'd tackle this concept of drone types and pre-slave characters, I hit upon another idea:

Why create so many drone characters when I can dynamically change every character's properties anyway?

I plan on having lots of characters in my game, and the prospect of creating so many characters, and typing out all the properties for each character etc frankly does not inspire me at all. Now I very much plan on extrapolating all actions into Timers as possible, so as far as I know, I only need to maintain a list of character names, portraits, and attributes in an MDA, and a few template characters and we're good to go!

Now the problem with this is, you can only have as many characters in the same room as you have dynamic characters, so a decision had to be made. I chose 3 but this can be easily extended by duplicating these dynamic characters anyway. All actions will basically be "parse the character name to the timer" affair so there will be little to no code tweaking within the characters themselves.

Second problem - how do you now track what characters are in which room now? It's a serious question as well, since you can't just leave your character in a room and forget about them - and the solution why simple conceptually, does take some coding with an "On Each Turn Timer" - keep track of where your characters are with an array and move them into the room (and don't forget to move other characters out).

For efficiency reasons I chose to keep them on the map template so you don't have to loop through all your characters each turn, so I just have to pick the room name from my array (using direct array ID reference) and figure out who needs to be here, and convert my template characters into appropriate characters.

So far so good. But why stop at characters? Next time, I'll talk about dynamic rooms.