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.
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.
*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:
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.