console

Code Finished

Overworld

I have now finished the creation of actual features in the game, and I hope that I’m done with tuning/removing debug items, because I don’t think I am going to check any more.

I have implemented all of the features specified in a previous post.

The final release on GitHub is here.

Advertisements

Progress

My work so far:

01_map

This screenshot shows some teaser code, and a demonstration of my ASCII map, with a rogue-like at-sign-character carelessly splashed across the map.

There are four commands so far:

  • move: randomly moves the player to a different coordinate on the region
  • travel [north | south | east | west]: changes the coordinates of the current region according to the direction specified
  • spawn: randomly places an asterisk on the map
  • exit: terminates the program

Party Grinding (not to be confused with grinding party)

One thing I want to achieve in py4school is a lack of grinding mechanics, which in my opinion damage the replay value of games; (which is in turn at odds with the purposes of random generation.)

This, however, leads to a problem, in that I indeed need some kind of character growth implemented in-game; the first thing that comes to mind is to implement a kind of grinding that deliberately and exclusively holds complicated gameplay back from new players.

In order to implement this in a normal leveling and exp way, which I’d like to do, the best game feature I can think of is a reputation/fame system; (fame is also a nice tie to the Diablo roots I’m embracing.)

Fame would affect the amount of followers you can keep, holding back the complexity of optimizing multiple characters, allowing you to practice and master the usage of 3 followers before you start playing with 4, or say, the usage of a new class without any followers before you start playing with a follower.

And with this I add that my aim is to make less of an RPG ‘idler’/’infinigrind’ (new term!) and more of an RPG puzzler, relying on stealth and choices to take out enemies in a non-direct way, all in a quasi-medieval age of civilization.

P.S.

There will be more than one system determining your maximum party size, however the raw grinding aspect is the one that both gives the complexity to players who fail to prove experience more efficiently, and that allows players easier victory when struggling, as well as satisfying the criterion of the assignment!

Initial Design Ideas: “Extradite”

Looking at my goals for this project, I have worked out multiple ideas for a general game structure, and this one is the one I like:

Extradite.

You are set in a residence a short distance away from an unknown city, having been extradited from your old home (from which you are now much farther), and must survive either in the wilderness, in the urban community, or in the depths of your adventures. (Hell.)

This setting opens up three primary linked stories, and to an extent you will need to participate in all three, but which ones you thrive in are up to you, and your character preferences.

The game has three layers:

  1. Text interface
  2. Area map
  3. World map

The text interface is the input and output for the game, whereas the area map is just an auxiliary to this.

The world map simply names the different regions as they appear geographically, and although the game could be enjoyable with personal memorization of maps, (Minecraft!) I have a marked criterion to meet, so that is what I shall be exploring: map integration in a geographically driven survival/exploration/adventure game.

I also have some more story in mind but that shall be discussed in the future, and finally:

I’m not going to use the geometry system for actual controls; there shall be no “move (1,1)”, no “move left” and definitely not any “goto (547.8, 38664.2)”.

New Blog! (Not Really!)

Blogging about blogging is boring so I apologize for being boring, (also apologizing is boring so I apologize for that as well)

BUT

I am starting a new category corresponding to blog posts that relate to a school project I need to be doing.

It needs to be in python so it is rather different to the entire purpose of this blog, but maybe I’m okay with that;
It also needs to be a text based adventure, but I won’t be redesigning Zombies for that, I also won’t be making an engine for this, but rather just a normal text adventure implementation.

The criteria I shall be working around can be summarized as follows: answer the question. (School.)

This means I will need the following:

  • A map system incorporating rooms and/or areas.
  • An inventory which has functional contents that can be manipulated.
  • Travel.
  • Leveling/character growth.
  • Battle algorithm/s.

(Although battle isn’t specifically defined… but I want to explore the obvious definition anyway, so classic RPG it is.)

In terms of personal interests I’m going to be exploring the way that grinding/monotony exists as a trope in RPGs, and how that is/isn’t optional, as well as the applied ways that item functionality interacts with crafting + recipe systems in terms of things which I don’t fully know how to explain at this time.

That’s all!

My Super Cool Storage Design For Video Games

This is an idea I have had in previous text based designs, that I think I shall finally implement in my zombies project:

It is a system for determining how much stuff can fit inside a storage container;

It works by using hard coded dimensions for the sizes of objects and containers, (rather than a “size” attribute that directly determines how much storage it occupies.)

Then two processes occur to check to see if it could probably fit in:

First it checks to see if the object could fit into the container if the container were completely empty:

  1. Arrange the dimensions of the container in descending order, have a biggest, middle and smallest.
  2. Do the same for the object being fitted.
  3. Compare the respective sizes,

if any of the three object dimensions are greater than their respective container dimension, the object doesn’t fit.

Then it performs a check which is equivalent to the usual “size” attribute check, using the volume of the object and the volume of all other objects and the liquid capacity of the container to check the plausibility of the object fitting.

If both checks succeed then the object fits fine. This system isn’t quite perfect, but it is very good.

Of course not all objects are a simple cubic three dimensions, so three dimensions must be chosen that encompass the object for the sake of the algorithm, although most objects will have square or circular bases (buckets, sticks, kitchenware) and the latter can simply be translated to the former.

The empty space that is ‘wasted’ in this process by rounding circles up into square objects compensates very well for the fact that some situations are completely impossible but pass both tests anyway. In other words, since there is no actual tetris involved in the storage process, there is a space penalty.

Now in terms of benefits, this system provides variety, in fact, this system can create gameplay by providing situations in which the size of containers needs to make you think about how you are going to sort your possessions to deal with them.

Now all I need to do is think of something to make that a good thing, and not just completely annoying.

Lasagna and You: Coding in Layers

For the text based project  I am working on, I am embracing a thing called lasagna code, the use of distinct layers in a program’s structure. Since I am using C++, these layers also show in my file structure, I have main.cpp, command and eco.cpp, all alongside their relevant header files.

Lasagna code to me has two main good points, and one main bad point.

Lasagna code is easier to visualize, and harder to forget:

Most of the time we forget the details of our programs almost as soon as we stop working on them for a few minutes, but having a visualization of how you made something makes it much easier to remember how it works. Spaghetti code tends to just be spoken in a stream of consciousness, and is much easier to forget as a result.

Lasagna code is more portable:

It is easy to visualize separating layers of cooked lasagna; you have two distinct layers of pastry separating without objection, and a whole lot of meat/vegetarian filling that doesn’t know which way it wants to go.

That is exactly what seperating layers of lasagna code is like, your two main functionalities (in my case, user input and world/item management) are easy to identify and seperate, in fact they are already completely separate, their is no interaction whatsoever between command and eco.cpp; the interaction happens in commands.h*, which has functions that take input interpreted by command, to pass that input to world functions in eco.cpp.

As a result completely rewriting certain layers, but not others, can make dramatic changes to the program, such as:

By replacing the user input layer with an autonomous layer you can create bots to run a ‘simulation’ instead of a game. Creating an output layer on top of this would give you a finished product.

By replacing the system of input, you could create a windows based application and set up your own gui to collect input, but once you have done that, if you are passing the same strings to the rest of the program, command and eco.cpp remain completely unmodified.

Lasagna code is a massive pain:

Dealing with multiple layers of code can be bothersome.

In my example, creating a new functionality, like deleting objects would go something like this:

eco.cpp: create function bool deleteItem (LocId todel); to delete an object

commands.h*: create function int C_delete (string arg); to cast user input into the number associated with an item
(I know that making users type in numeric identifiers is bad, but it is temporary, we are still only making a delete function for the first time at this stage, after all.)

main.cpp: add entry to the hard-coded list of commands that looks something like this:

+ command (“delete”, C_delete, ” “)

which quite simply specifies the string the user should enter to invoke the command, the function that will interpret the other arguments, and the delimiter that that part of the function will use.

This is all neat and fine, and this is what I had in mind when I decided to use lasagna in my coding style for this project, but it makes the production of secure code just that little bit more bothersome when you need to create checks for invalid LocId input, and then pass back a return value that represents that, and then interpret that again to determine what to display on the screen.

Summary

Basically what you are actually doing when using lasagna code, is developing a number of discrete API systems, and integrating them in a way that gives you an actual product to debug and play with, instead of the much more lifeless alternative of creating an API entirely without using it, which sounds fun, but can slow down quite quickly if you are an indie game developer instead of a large company with monetary incentives.

So despite the massive pain, I would recommend it if you are planning on doing versatile things with your program. Three layers to integrate at once will save you making three entire reproductions of the program, and that is reassuring.

If you are working on a small learning project, or a proof of concept, just throw it together; if it compiles right, it doesn’t matter how you did it until you want to make changes to the program – save the serious and secure building for when that happens.

p.s.

*commands.h is a header file for main.cpp, I have another file named command.h, (a header for the file command) although it is invoked as such:

#include “..\header\command.h

as opposed to the former file, which is in the same directory as main.cpp.
I plan to develop the graphics based project in a lasagna format as well, it is just that for the time being I am focusing on getting win32 working well, and am not actually working on gameplay at all at this stage, for obvious reasons.
I have already started to separate my file structure though, and I know how I am going to place my layers when I do.