Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comment
  • views

About this blog

Fumbling my way towards programming competence

Entries in this blog


Early Retrospective

It's been a while since I've posted. Unfortunately I've had several real life obstacles come up that have really cut into my programming time, and as I'm not a terribly good or fast programmer that has been doubly challenging. Plus, I was unsatisfied with some of the functionality of my console game library and ultimately decided to port it to SFML, improving it along the way. Essentially re-doing stuff you've already done when you want to make a game makes it hard to stay motivated.

I've also decided that my previous approach to this journal was less than ideal. I think that rather than posting walls of text about my plans, I will do better by posting descriptions of things I've actually implemented along with any observations I've made about what did and didn't work. I'm still always interested in any comments, questions, or critiques on anything I've posted. Especially critiques.

But to kick things off, I wanted to share some observations I've made as an amateur developer.

You should work every day. There's so much work to do in developing a game, even a small one or a demo, that it's easy to be overwhelmed by it. It's also easy to be overwhelmed by what feels like a lack of progress. That's why working every day is so important. The amount of work that you can realistically do in a day forces you to work in smaller units. And even if each day's work doesn't seem like much, over time your accomplishments really add up to significant progress. Not to mention it can be hard to pick up where you left off with a gap of even just a couple of days. If your code is like mine, it's not commented as well as you think and your design approach isn't as clear or obvious as you thought.

You don't need to work with your compiler or IDE every day. Design is work too, and good design especially is a lot of work. Spending your energy putting together a solid design or approach to a problem is at least as productive as hacking some lines of code together. I've found that when I've fired up Visual Studio I feel pressured to write lines of code, and I am not skilled enough to design well on the fly. Poorly designed and/or poorly written code will likely need to be fixed later, and for me trying to program without insufficient thought in advance costs me quite a bit of time rather than saving any.

Design is the most difficult programming task. When I'm working on design for a feature I want to implement, I identify the specific problems that need to be solved by the code I write. Without a clearly defined problem to solve, my code tends to come out as a big mess. It's functional for my immediate needs (like testing and prototyping), but tends not to be very expandable or flexible. This leads to either very convoluted implementations of other features later on, or a significant re-design of that section. Since I've ended up doing the design more rigorously eventually, there isn't much reason for me not to do it upfront. In all cases so far, writing code to execute my designs has been far easier than creating the designs themselves.

The job of a software designer is to manage complexity. Okay, I stole that line from Code Complete (2nd ed., if it matters), almost certainly misquoting it in the process. But it's true. Even programming tasks that are well within my level of technical ability dissolve into rubbish if I forget this concept. Making software is hard, and if you cannot break what you are doing into chunks small enough that you can hold each one fully in your mind while you're working on it you will run into trouble. I try to check myself by reviewing at intervals: What is the exact purpose of this section of code, or this function, or this class? If you can't answer this question for the section you're working on, you are extremely vulnerable to losing focus and having that section not work as you intended. You might get lucky, but generally (for me) there's no happy ending when I can't provide such a definition immediately.

Implementation is experimentation. For a fairly low-skill programmer like myself, even after intensive design work some of what I write just doesn't work well. In these cases I have tried to come up with entirely different approaches than I attempted previously, using my poorer try as a reference. It's important to recognize that even though a section of code may produce something like the result you want it can still have any number of problems. You can't be afraid to refactor or, if necessary, re-design any portion of your work. Any problem that you notice isn't just going to go away on its own.

Focus on one task at a time. It's easy to bounce around to all of the different tasks you need to complete to make your game, which in turn can make it very difficult to stick with the specific feature you're working on. Often a simplified or dummy class version of a game feature is enough to let me test what I'm developing, but the temptation is always there to do more. This has been especially true for me in the case of very interesting features. But I know that if I let myself be distracted from necessary work I can quickly fall into a habit of leaving tons of half-finished features behind me. This is bad for prototyping, because there will be a lot of work with nothing demonstrable to show for it, and also leads to poorer design, as above.

Even a good design isn't sacred. Even with very little advancement on the gameplay features of my project, I have recognized that a lot of my ideas are unlikely to work all that well. This includes features that I have designed down in minute detail. Among others, my ideas on a schedule-driven game as well as Mad Libs style actions seem like they would not be much fun. While it's a shame to not use the designs that I've put a lot of time into creating and can implement, it would be much worse to have a game that forces the player to engage in clunky and un-fun activities.

A beginner's designs will typically not be that great. There's always something to improve, but at some point you have to produce some code and test it out. There is almost certainly a better, cleaner, faster, more elegant approach than what you've done, but you won't know what it is because you're a beginner and not an expert. A lot of the difference between a beginner and an expert is experience, and you won't get enough of that if you constantly rework sections of your program to improve them; you certainly won't finish your game. Write something that seems like it will work, and then test it under a variety of circumstances. Then ask if you are getting the results that you want. If not, then try again. If it seems like it's working as you intended, then move on. If there's a problem that needs to be fixed, I promise you it will come up later. Until then, keep working towards completion of your project, not perfection of one tiny segment of it.

A lot of things a game needs don't feel like game development. My current project will use a menu-based interface. But developing that interface means working on things that have nothing at all to do with the game proper. The most dispiriting thing I've experienced so far has been imagining all the exciting features I want my game to have (designing specific characters, locations, abilities, and so on) and then sitting down to create popup windows and properly functioning menus all night. It's necessary to do, but approximately 0.001% as fun as actually working on game features has been.

Use what you already know. Following from above is my strong recommendation that you use skills you already have to make a game like the one you are envisioning, even if you don't think that it is ideal, if you want to get to work on the "game" parts of your project quickly. If you know Windows Forms, use those to make your game interface at least for the prototype so that you don't spend a lot of time learning things like setting up an interface in SFML. It's good to develop your skills by learning new things, but working on non-game elements of your project isn't fun in the sense that creating game features is. I really wish I had just used a simply number based menu and input system in my prototype rather than trying to create fancier GUI-style menus. I'm a better programmer now than I was before, but not much further along in my game's design or implementation.




More Prototyping

Sorry it's been a while since I updated, real life took up most of my time over the last week and a half. I've been refining my design for a prototype, and figured that my progress might be worth posting.

In making the prototype, I've thought about what elements are most important to my concept so that I could focus on something manageable to get up and running. I'm glad that I focused on designing very small chunks of the program, because there are a lot of details that I managed to overlook in the design work I've done so far.

The central aspect of my game is the investigation, so I've started working on that. The keys to the investigation mechanics as I've envisioned them are:

-Every action a character takes must leave some sort of trace behind, whether or not any other character is capable of perceiving and interpreting that trace

-Traces include physical evidence, supernatural evidence, and eyewitness accounts

-Characters need to be able to control how discreetly they carry out actions to influence how many traces they leave, and how much information these traces contain

So my prototype will need to contain characters, some possible actions, locations, and the ability for characters to make observations.

Characters are easy enough since I don't need them to be fully implemented. For now, they just need names (so that they can be easily told apart) and a couple of stats related to observation and concealment.

Traces are more complicated, but they don't need to be fully implemented either. To get started, a eyewitness accounts will be the only trace I deal with. Later on I plan to have a specific container class attached to items, characters, and locations which can hold information representing the other two types of traces.

Variable discretion in carrying out actions is already a part of the action system that I've been working on, so for the prototype it's just a matter of implementing the action system in conjunction with the eyewitness observation system.

For my initial tests, I'm planning on coding a single location, a player-character, and ten NPC's to serve as potential observers. I'll also need some more abstract classes to allow the player-character to define actions, a system for resolving actions, and a system for resolving potential observation. There's obviously a lot more that needs to be done, but this seems like a realistic initial challenge to tackle, and it'll all need to be in place before more features can be added.

For anyone who wants a bit more design detail, I've added a brief overview of the Action and Observation systems, which are a lot more complex than the other (very basic) elements of the prototype. If you're interested, please take a look and leave comments on what you think of the design and my presentation of it.

The action system:

As I layed out in a previous post, my action system will have a grammar-based structure. Only certain combinations of parts of speech are allowed for each action, and only certain types of objects can be used in a given part of speech for a given action.

For example, the Go action requires a destination (the part of speech is an indirect object) and a adverb determining how secretive the character is in moving there. The destination must be a Location object, and the adverb must be from an Enum I've created for this purpose. So a character might choose "{Go} {park} {casually}". I'm calling a completed structure like this an "action-phrase".

Each action-phrase has its own construction screen, which ensures that only appropriate parts of speech are used and also ensures that only appropriate object types are used in each.

Once an action-phrase is constructed it is sent to a function called "ResolveAction", which is part of a static class. ResolveAction takes the Action-phrase as an argument and then parses it by the action chosen (the verb of the phrase, sorted by a switch statement). The appropriate case then calls a specific function which contains the formulae needed to determine whether or not the action is successful.

The observation system:

While resolving an action, checks are made of NPC's in the area to determine whether or not they observe the action, and how completely they do so.

I haven't worked out exactly how the formula for this will work, and anything I choose will have to be tweaked a lot anyhow. But for now, each character in an area has a chance of noticing an acting character.

For each NPC that successfully notices the acting character, additional checks will be made to determine how many details the NPC observes. These details are the components of the action-phrase being resolved. Finally, a combination of how secretively the acting character was behaving and how much detail the NPC noticed determines how strong their memory of the event is.

Any observation made will be recorded in a master list of observations, which represents all of the information that a character could gather by talking with witnesses. Over time, characters will forget details about things that they witness. The rate of this degradation will depend on the strength of the memory. When no characters still recall any detail of an event, it will be removed from the record entirely.

So a completed observation will include:

-The identity of the observer

-The identity or physical description of the character observed

-A copy of the action-phrase that the observer witnessed. The more details successfully observed, the more exactly the observation will reflect the action-phrase being resolved

-A measure of how strongly the observer remembers the event observed

However, for initial tests I'll probably just have a text output state whether or not an NPC noticed the action taken by the player character, and if so print a a dummy version of the observation. I don't think that the master record is crucial at the moment, nor do I expect it to be all that difficult to create once I'm more confident that the observation system is working.




Prototype Design

I've been fiddling around the last few days with my design document, and many different elements of the game are coming into focus. However, the scope of the document is pretty big already and a lot of elements can't be defined until more fundamental pieces are established.

To avoid overlooking details, I think that this would be a good time to lay out the design for a prototype. This will assume a text-based user interface for now (I've already got a library for it) and will make sure that the framework for the game works properly with other core elements, as well as providing some reason to think that more complicated design elements will work as planned.

This is an excerpt from a larger document, so some of the formatting may not appear correct. Other formatting is likely actually incorrect. I've tried to keep this entry self contained, but there may be phrases or formatting which relies on standards set in the whole design document. Two items that I noticed:

-"Investigator" refers to any character who actively tries to identify major characters and/or solve crimes. Each major character in the game is an Investigator, and there will always be at least one Investigator NPC working for the police.

-"Empowered" refers to a character in the game who has gained access to a supernatural ability. All Empowered characters are automatically Investigators.

I am very interested in any feedback that anyone has. Specifically I'd like to know where my design, documentation, or any other "practical" deficiencies in planning are. This includes awkward systems, unclear writing, overly-ambitions designs, and anything else you may notice. But I'm also interested in observations about gameplay mechanics or anything else as well.

Prototyping considerations:

The key entities that need to be created to establish a functional prototype are as follows:

-At least one power
-Ability system
-Investigation Notebook

Even this is beyond what I think I can plan well, so I'll be focusing on a few of these elements to sketch out a bare-bones prototype. They are marked below with a (1).

2.1: Characters (1)

Characters need to have names, locations, core stats, and inventories. Each Action that can occur between characters must be defined. Characters will be in one location per time period, and can move only between time periods.

2.2: Locations (1)

-Locations need to contain a list of characters in each, as well as functionality for searching through and modifying these lists. They will need a similar list for items.

2.3: Calendar/Schedule (1)

The calendar needs to contain dates, a week's worth should be enough for the initial prototype. Each date will contain its own Schedule, which is a list of that day's time periods. Each Schedule should aggregate scheduled activities of each major Character. The schedule will iterate through time periods, resolving the activities contained in each. Once the final time period is processed and resolved, the calendar will advance one day. Schedules should be generated immediately after the Calendar is advanced to the next day.

2.4: At least one power (2)

This will be important in a later iteration, but is not strictly necessary for establishing the more rudimentary elements needed for the prototype. Setting up the Calendar and Schedule and having them interact correctly with Characters and Locations is a more fundamental concern at this time.

2.5: Action system (1)

All of the actions that a character can take will need to be defined, perhaps as an enum, but more likely as a distinct class. The rationale for this is that while an enum can be used to denote a type of action, or a modification to an action, additional information will be needed to fit the action into the overall ability system. This could be managed on-demand by an action parser or something similar, but it might be smoother and easier to have each action supply possible combinations. Certainly each Action should contain information regarding what types of objects can be associated with it.

So an Action will need to contain an enum indicating its type, but also should hold information like what sort of objects it can be used on, what statistics are involved, and so on.

When the user selects "Action" from the menu, a list of possible Actions appears. When the user selects one of these actions, the chosen Action appears at the beginning of a line, followed by several blanks, braces, or other marking showing how many modifiers can be attached to it. When multiple forms are possible, one should be displayed by default. I'm not sure whether this should be the simplest, most "natural", or the most complex action. This list, the Action and its permitted modifications taken together, is the "action-phrase", which determines the specific manner in which an action will resolve.

Most actions may have a direct object (what object the action will operate upon). Some may have an indirect object (to whom or what the action will be done). Actions may also have an adverb (how the action is to be done). Some may have a preposition (where the action will resolve). Some actions may have a duration. The player does not necessarily need to fill all blanks, and actions will be slightly different depending on whether or not some blanks are filled.

For example, if the player selects "Action"->"Drop", the screen will display {Drop}, with a blank immediately to the right. The player will select from a menu (dropdown? subwindow? list of options?) what will be dropped. From the definition of the Drop action, the only things which can be dropped are items currently equipped or in the player's inventory. So the list of options for the second blank will be populated only with such items.

After choosing which item to drop, the player can execute the action to drop the item wherever he happens to be, or can go on filling blanks. The next blank is either an indirect object or a preposition--the player can select another character (placing the item into her inventory) or a place (some objects can fill this list, like tables perhaps? Any object with its own inventory capacity should be fine).The final blank is an adverb, and the player can execute the action discreetly, casually, or obviously. The action then executes according to the options that the player has selected.

Default actions (less than all blanks filled) will need to all be defined, as well as all valid combinations of options. This should be manageable by selecting each action in turn, and deciding what modifications will be permissible.

For action-phrases which involve items, the items themselves may have restrictions on how they can be used. Even if a given action-phrase form would normally allow a duration to indicate how long the action can persist, if an item is listed as the direct object and that item does not allow a duration then the duration blank will not appear.

One possible interface element that might help this system would be to display a sentence which describes the Action-phrase in a more conversational way. So, {Drop} {pencil} might display "Drop pencil where you are", while {Drop} {pencil} {Ronald} {obvious} might parse out to "Give pencil to Ronald", and {Drop} {coin} {Ronald} {discreet} might parse as "Slip coin into Ronald's pocket". I'd like to avoid having players remember arbitrary combinations of words to execute actions, but such a parser might be more complicated or slow to write than I'm currently envisioning. This is probably a secondary issue, to be addressed after the prototype is working. I can remember arbitrary combinations for now.

2.6: Observations (2)

Observations should be very similar to the action-phrases detailed in 2.5; indeed, they should be roughly the same with an "observer" clause tacked on.

If the actor observed executes an action like {Take} {wallet} {table}, that would indicate that the actor took a wallet from a/the table. The observer record should then be {Observer} {[mode of witnessing]} {[actor observed]} {take} {wallet} {table} {succeeded}. This carries the same information as the action-phrase, but has a couple of significant additions:

The observer is listed, which is an important factor in logging the observation in an investigation notebook.

The "mode of witnessing" section describes how the observer made her observation. This can include seeing, hearing, feeling, etc., but can also include things like having heard a rumor.

The actor observed segment is self-explanatory, though it should be noted that it can include the actual identity of the character observed or a description of the character observed, depending on whether or not the observer knows the character.

The action-phrase segments are the same as in the system laid out in 2.5, it carries the same information that is used to resolve the action. In the event that an observer cannot fully perceive or understand an action, these can include placeholders, such as {Take} {something} {table}, and so on.

The final segment carries information regarding the outcome of the action being observed once resolved, presuming that the observer was able to perceive and understand the result. Success indicates the action was resolved successfully, failed indicates failure, and unknown indicates that the observer does not know.

The quality and granularity of observation depends on various statistics of the observer rolled against corresponding statistics of the character being observed. Most events will not be recorded by any character; indeed, only characters above a certain Importance threshold will take actions that can be observed at all. Of these, few may be conspicuous enough to garner the notice of a random character.

Any observation made that a character will "remember" will be logged to a master dictionary made up of a composite data type which will store the observer(s), date, time, and location as well as the observation itself. As long as the character remembers the action, its entry in the master dictionary will persist and the player can gather the information by successfully interacting with that character.

2.7: Investigation Notebook (2)

The investigation notebook is a record of observations made by characters as reported to an Investigator. Each Empowered character will have a notebook, as will the police Investigator. Additional Investigators, should any arise during the game, will also gain investigation notebooks.

The notebook includes an automatic record of things that the character observes directly. If, while observing the park, the Investigator sees another character doing something that arouses suspicion, a note of that will be entered into the notebook to the maximum precision that the Investigator can observe. This will be stored as described in section 2.6.

The record of distinct observations will be comprehensive of all observed events by default, though the player can remove entries manually and possibly set up rules by which some observations will be discarded. This will be nailed down when the implementation for the Investigation system is undertaken.

The record will be sort-able on demand, allowing the player to quickly sort observations by date, observer, action, or any other segment which can make up an observation listing.

The player will also be able to designate certain items to be added to short-lists, sets of potentially related observations that the player currently finds relevant or important to follow up on. This is just another list, but a much smaller and player-determined one so that the player has access to information of interest at-a-glance.

2.8: Items (1)

Items refer to objects that characters and certain other objects can contain. There are different types of items, but all items will have a name, a description, a weight(?), and a size. Other items will have stat modifiers (i.e. Perception +2), lists of objects they can be used on (i.e. characters, equipment, etc.), and possibly other considerations. Some items have an inherent inventory capacity, which is added to the player when the item is worn and serves as excess storage when not.

2.9: AI (3)

AI will govern behaviors for NPCs. This will obviously be a rich and complex section, but it is well beyond primary and secondary planning considerations. Many other components of the game will need to be up and running before AI can be meaningfully planned and implemented.

Now, on to my more task-oriented list for producing a prototype of the primary elements only.

3.1: Characters will need to be defined as outlined in the full design document. They will require:

-Locations (field, requires Locations to be defined)
-Personal schedule (requires Schedule to be defined)
-Core statistics
-Inventory (requires equipment Items to be defined)
-Function updating location (requires Location to be defined)
-Functions for updating personal Schedule (requires Schedule to be defined)
-Functions for constructing action-phrases (requires Action to be defined)
Additional character data can be filled in as the prototype is expanded.

3.2: Locations will need to be defined with a name, description, a list of characters presently within them, and a list of items within them.

-List of characters (requires Characters to be defined)
-List of items present (requires Items to be defined)
-Functions updating list of characters
-Functions updating list of items

3.3: Schedules will need to be defined as a container of times, locations, and activities.

-Name (day of the week)
-Date (requires Calendar to be defined)
-Time segments (blocks)
-Location (field, requires Location to be defined)
-Activity (field, requires Action to be defined)
-Functions updating time, advancing to the next block (needs to signal a function in Calendar, to trigger all updates for characters whose Schedules are being checked. Requires Calendar to be defined)

3.4: Calendar will need to be defined as a series of days (Schedules, which will be empty when generated and then filled in)

-Container of dates (day of month, month of year) and Schedules (requires Schedule to be defined)
-Current time (hour and minute)

3.5: Actions will need to be defined, and each action will need to list what forms it can support when extending the action-phrase. The Actions to define are: Go, Talk, Item (Use, Give, Drop), Use, Take, Attack, Observe, Examine, Search, Ability.

-List of allowable forms (i.e. direct object->adverb; direct object->indirect object; direct object->indirect object->adverb; etc.)
-List of object types that can fill each segment of an action-phrase (requires each object type so used to be defined)
-Class definitions for each action will need to be written, inheriting from a base Action class
-A parser or manager will also need to be written to handle action-phrases

3.6: Items will need to be defined, at least for a small set of objects. These are not now "functional" items, in that they cannot be used. They can, however, be picked up, dropped, given, observed, and examined.


That's what I've got for the prototype so far. Clearly there's more work to do before moving on to making the prototype itself: some of the Actions are redundant or awkward, their combinations still need to be laid out, and some major game elements are still on the backburner. I think that a couple of diagrams might also be useful. But I'm hoping that this is an OK start.

Does anyone have any observations, advice, questions, complaints, or anything like that? I look forward to hearing them.




Project Overview

I realized this morning that my intial journal entry was about as dull as possible. If anyone cares about this journal at all, they'll care about the project, so it's probably a good idea to talk about that rather than an empty journal post about how I'm starting a journal.

The working title is Gekkoukan High, named for the school in Persona 3 which is a major influence for this project. Other significant influences include Vampire: The Masquerade and Future Diary.

The game centers on events in a medium sized city, with mysterious figures jockeying for advantage in advance of an even more mysterious oncoming catastrophe. The player takes the role of a high school student who finds him or herself empowered with supernatural abilities. The player character is not alone in gaining such abilities, however. Some few other residents of the city have gained their own distinct powers, and utilize them for their own ends.

The player's goal is to investigate the city in order to identify these others, and also to develop his or her own abilities so that they can be dealt with once identified. Can the player successfully find his or her rivals in the sea of unsuspecting residents? Can he or she avoid detection? And can he or she find some way to stop these rivals before their designs are realized?

The game will include between eight and twelve distinct types of supernatural power the player can wield. Each will be geared towards a particular play style, but players will not be forced to play that way. Depending on their power and preferences, player characters can be strongly focused on physical combat, frustrating investigators, controlling and manipulating others, summoning minions, enacting curses, and more.

A major play element will be investigation. Players as well as NPCs will have to search for clues, question witnesses, and sift through collected evidence to identify other empowered characters. Once identified, the player can choose how to deal with them. The player may reveal him or herself in hopes of forging an alliance work quietly to subvert the other's plans, or pursue more permanent solutions. At the same time, rivals may be closing in on the player without his or her knowledge. The player will have to balance making more overt efforts to achieve goals with the increasing risk of discovery such action brings.

My goal is to produce a game in which the player is subjected to a tense cat-and-mouse scenario with unknown opponents wielding unknown powers in the context of otherwise ordinary high school life. I'll address gameplay elements in more detail in future posts, but this at least gives a broad overview of what I'd like to produce.




Setting Out... Again...

I think that design is underappreciated as a part of the programming process with hobbyist game programmers. I know that when I started programming I badly neglected design, and I wasted a huge amount of time because of it. A clean design makes the actual programming far easier to execute, and design flaws can present themselves as brutal programming roadblocks. As an inexperienced programmer I had a difficult time distinguishing between the two, and spent a lot of effort coding elaborate work-arounds to compensate for designs I didn't even know were inadequate.

I've learned a lot about practical software design through trial and error, but I'm still not skilled enough to design all that large a project on my own. I'm currently taking a break from a fairly small project which I'm a bit burned out on due to design issues. I'd like to do some design work on something new in the meantime, and then use what I learn to revisit some of my previous efforts.

But as I look at another project I thought, why continue the pattern? Rather than waste weeks of my time learning about design by doing it poorly on my own, it might be a better idea work on the design document in public.

I've still got some work to do before any portion of my design is post-able, but I thought that I would post my design document piece by piece and hopefully get feedback on it. It'll be valuable for me to get others' input, especially from a software design perspective. Hopefully other inexperienced programmers will be able to get a feel for how design goes from ideas to a clear and executable design document as well.

My primary goal is to write a design document that translates cleanly into code, though input on game elements, fun factor, and so on are also welcome.



Sign in to follow this  
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!