I have an interesting idea for a collaborative project. You are probably familiar with the Wario Ware games, in which the player has a limited time to complete several small “microgames”:
Planet Virtual Boy should develop a collaborative Wario Ware game for the virtual boy, in which programmers can submit a small independent microgame and add it to the game.
The idea is that the main game has a common include file, but authors write games in their own private c files and submit them. The common interface has things like the key presses, and the time remaining.
We use a struct to give the main loop the necessary info to run the game at random:
struct MICROGAME{
const char*instruction;
const char*author;
void(*init)(void);
void(*microGameLoop)(void);
void(*draw)(void);
enum time time{SHORT, LONG};
};
The “instruction” field is the message that pops up before starting a game.
The “author” field will be used in credits.
Each function pointer is called by the main game loop to simulate the game.
Finally, time specifies to the main loop how long the game should be active.
The author writes their game in their own .c file, keeping all state for that game static to the .c file they wrote it in, including any libraries they will use. The author exposes the struct with their own header file, and we place a pointer to it in an array. A random function chooses a game from this array, and ends the game when time is up.
struct MICROGAME* game_list[]={
…
};
If everyone designs one simple microgame, we could have a great community-driven Wario Ware homebrew. The design will be expandable, all we need to do to add a new microgame is add a new pointer to the array and recompile.
Would anyone be interested in something like this?
The idea is cool and I’d probably like to contribute a game or two. But I’d propose a different approach:
- Don’t use any copyrighted material but make it an original game
- Build the game framework as a VUEngine project and push it into a public code repository (preferrably Git). Instead of that struct, have a minigameBaseState which all mini games inherit from.
Would echo KR155E’s sentiments: it’d be nice if the games were original, definitely great if the code was in a public repository, and having something mini games inherit from would benefit streamlining the whole process (and is basically what syncophono seeks to do with the struct).
Sign me up for making something for this btw. 🙂
Making it original is a great idea! Though, not sure what to call it. VBWare?
A repository like github would certainly aid in the open development process, I like it.
The VUEngine would be a useful tool in microgame development, especially with the new release.
What is the purpose of using inheritance? My intent for the microgame struct is to give the primary game access to each subgame’s functions. The data for each microgame can just be global and static inside its own file:
—-Example Microgame file:
#include “common.h”
static int exampleData, moreExampleData;
void init(void){
exampleData=0;
/*Called once at start of game*/
}
void update(void){
exampleData++;
/*Game logic*/
}
void draw(void){
…
}
/*Fill out function pointers here, the only part of the file that is given to the primary game.*/
const struct MICROGAME_INFO example{ init, update, draw };
—-
If we do it this way, a microgame creator can just write their game all in one file, without needing to inherit from anything. They can then include anything they want, such as the libgccvb or the vuengine. Of course some basic functionality can be given in common.h so that devs aren’t doing the same initialization in every file.
- This reply was modified 7 years, 8 months ago by syncophono.
So, after reading over @syncophono’s reply and pausing for a second, I think I am/was still in the C++/C# mindset. C doesn’t have inheritance unless you implement it, which uses structs (if I’m not mistaken?). Plus, not sure why someone would want to extend the struct anyways, since any additional functions would be called in one of the functions that has a pointer. @KR155E, what would be the advantage of creating an inheritance? (Feel free to correct me, I’m super rusty with C.)
On a side note, @syncophono: I’d be pretty keen on being able to pass some optional information between games, that way a microgame developer could leverage it for their game’s initialization. (Like having the player’s character position be passed, if that were to be available. That way, the next microgame could start with the player at the same spot. Or maybe passing the score from the previous microgame [if there were one] to influence the difficulty of the microgame being made. Hopefully that makes sense… xD) In some sense this could be a situation where the inheritance may be useful (that way a microgame could pass arbitrary extra information in its struct, which another microgame could try to access if available?).
The VUEngine offers various OOP features like inheritance through macros.
The way I’d do such a game would be the following:
- The baseMinigameState would define all the attributes and methods a mini game has to have at minimum
- There’s no “primary game” running at the same time as the mini games, instead the engine would be directly executing the various minigameStates. Since these inherited from baseMinigameState, they include all the logic needed to execute themselves, start a new mini game and pass their variables over (good idea there, Twila!), etc.
- The various minigameStates hold their attributes like winning message, etc. and they have the ability to overwrite their base methods to customize, for example, how the remaining time is displayed
- There’s a global array that holds all the available minigameStates
That’s actually pretty similar to syncophono’s approach, but in VUEngine terms. 🙂
Very good idea…
I’d like to create a mini-game…
I’ll stay tunned to this post…
@Twila The state is global, so all you would need to do to retain the previous player position is simply not update it in your INIT function. However I recommend initializing all your data before the game starts. These games only give you a few seconds, and as such, its better for the player to have some familiar aspects to rely on.
@KR155E
I think there is value in having a primary game running in a main loop. The primary game keeps track of your score, lives, and the game speed.
Game speed is especially a reason there should be something calling a step function for each game. Because if we want to run at double-time, the main game can call the update function twice.
If each microgame had its own main loop and was running independently, every game would need to individually implement speed-up behavior on its own.
If the programmer needs access to the time remaining, we can expose it in “common.h”.
On game speed, what do you think about implementing speeding up? Is calling the update function multiple times adequate, or maybe some VUEengine parameters can be tweaked?
@Twila
The passes parameters should be less specific to the individual minigames themselves, but maybe based on how the player is doing.
For instance, we could pass if the player lost the last game, what the speed is, and the level of difficulty, ect.
The games can use these params to create these adjustments.
Something else to decide on: The key input interface.
Every Ware game has always complied to a specific set of keys and not deviated from it. The game boy advance game, for instance, used only the D-pad and the A button as inputs.
For the VB, which buttons should be used as this interface? Using every button on the controller would make picking up and playing the game in 5 seconds a little difficult. So we should limit ourselves a to a subset of the buttons on the controller.
I’m thinking the two d-pads as the only inputs allowed.
What do you think?
syncophono wrote:
Something else to decide on: The key input interface.
Every Ware game has always complied to a specific set of keys and not deviated from it. The game boy advance game, for instance, used only the D-pad and the A button as inputs.
For the VB, which buttons should be used as this interface? Using every button on the controller would make picking up and playing the game in 5 seconds a little difficult. So we should limit ourselves a to a subset of the buttons on the controller.
I’m thinking the two d-pads as the only inputs allowed.
What do you think?
As someone who would only be playing this and not contributing to it (I don’t have the skills, but am so thankful to those of you who do!), I thought of this issue as well. Simple, uniform inputs across each game would really simplify the experience for the players and avoid making the player learn complicated control schemes for what should be “figure it out on the fly” controls, level concepts and solutions a’la Wario Ware.
In my opinion the inputs should be the left d-pad and the A/B buttons, the “NES-style” control scheme is one that nearly everyone is familiar and comfortable with.
As for a title, since you’re deciding against using established IP and planning original games(which is awesome), why not ditch the “Ware” title as well and have a completely original name?
The title “Virtual Rush!” popped into my head while I trying to think of an example, so that’ll be my suggestion :p
Yikes (at me), just reread all your earlier posts, @syncophono, and realized you had already addressed what I was posting about. Sorry!
Regarding, the inputs: I do like the idea of keeping things simple. Personally, would vote on the two d-pads because it leaves a lot of flexibility. Out of curiosity (just thought about this): do games tend to have a feature for mirroring the keys (if the controller is symmetric)? (I know Guitar Hero did for left handed players.) Never came to mind since I’m not left handed, but may be handy for those who are since the VB’s controller is perfectly symmetric.
As for a name, I’ll default to @syncophono’s desires since they’re curating/starting this all! @Quaze: “Virtual Rush” sounds decent (though I get a bit flattened from all the “virtual” or “VR” inclusions in game titles on the Vive and Rift end haha; it’s everywhere, but we already know its likely VR stuff!).
@Quaze: “Virtual Rush” sounds decent (though I get a bit flattened from all the “virtual” or “VR” inclusions in game titles on the Vive and Rift end haha; it’s everywhere, but we already know its likely VR stuff!).
I agree, “Virtual” and “VR” have become a bit cliché.
How about something like “Mad Rush” or “Task Panic”? Another cliché, but both have a nice ring with “3D” added onto the end.
“Task Panic” is a pretty good name because it describes what you’ll be doing in the game. Though we shouldn’t add “3D” after it because some games might be 2D.
I’m leaning towards the “dual D-pad” controls. Its a unique feature of the Virtual Boy and we should take advantage of that.
We shouldn’t mirror the controls because I want START to be able to pause the game.
- This reply was modified 7 years, 8 months ago by syncophono.
@Quaze: “Task Panic” sounds awesome!
@syncophono: Not particularly attached to the idea, but, if mirroring were available to accommodate dominant hand, then the triggers would be reversed same for: A <-> Select, & B <-> Start. (It’d just be a top level mode that the player could select, though I’m guessing most left-handed players don’t care / just get used to right-handed designed stuff anyways.)
Allow me to address your points:
I think there is value in having a primary game running in a main loop. The primary game keeps track of your score, lives, and the game speed.
All those stats don’t need a primary game running, but just a manager that holds their values, potentially saves them to SRAM, and which each GameState (minigames’ base class) access to modify their own behavior or to update those stats.
Game speed is especially a reason there should be something calling a step function for each game. Because if we want to run at double-time, the main game can call the update function twice.
If each microgame had its own main loop and was running independently, every game would need to individually implement speed-up behavior on its own.
Calling twice or more an update method during a game frame would not be a very good way to affect the simulation’s speed. First, because you loose the ability to scale the game’s speed using lower than 1 steps (like to increase the game’s speed from 1 to 1.5); if the game consists of say 50 minigames, increasing the speed in the way you suggest will be a nightmare to balance since the speed progressing from the first to the last will be too big. Second, the minigames’ simulation will depend on their performance, and unless you have absolute control of it, you will end up with objects slowing down and speeding up not intentionally. Third, it could break other processes that may run asynchronously to the minigame’s logic (like VIP’s o Timer’s interrupts, for example).
To avoid those problems, and maybe others, but at the same time to achieve the desired effect, modern game engines pass to the update methods a deltaTime argument that can be scaled by the programmer. That way the simulation is not dependent on the game’s performance, the scaling can be non linear and async processes are not affected. The VUEngine’s GameState’s execute method passes such a value to the game objects, but it is only used to affect animations (that is, the engine’s classes only use the time delta to affect the animations’ speed, but derived classes specific to each minigame could use the time delta for other purposes), while things like physics simulations are updated by another facility.
Speed scaling can be implemented in a GameNameGameState class from which all minigames inherit. In this way, the “primary game” doesn’t need to exist, since it would just be logic shared by all minigames, achieving your goal of avoiding the need to reimplement on each one the same functionality.
On game speed, what do you think about implementing speeding up? Is calling the update function multiple times adequate, or maybe some VUEengine parameters can be tweaked?
As I said before, calling multiple times an update method during the same game frame wouldn’t be a good idea in general, no only in the context of the VUEngine. On the other hand, adding support for time delta scaling to the engine would be easily done.
If the programmer needs access to the time remaining, we can expose it in “common.h”.
By using inheritance, there is no need to use global variables. The time remaining would be a protected attribute of the GameNameGameState class accessible to all the minigames.
jorgeche
In this way, the “primary game” doesn’t need to exist, since it would just be logic shared by all minigames, achieving your goal of avoiding the need to reimplement on each one the same functionality.
If we were to use inheritance from the base game, each minigame would get unnecessary copies of the main game state. Only one minigame will ever run at a time, so the copies of main game state don’t need to be a part of the minigame at all. They can exist in one place independent of the minigames that don’t need to access it.
The purpose of a classes and inheritance is to create a template that you can create instances of. However, only one instance of a game will ever exist, so why make it a class?
If we are trying to encapsulate, we can encapsulate at the file level. If you make a variable STATIC inside a .c file, its the same as making a variable PRIVATE inside of a class: it can’t be accessed anywhere else, not even with EXTERN.
- This reply was modified 7 years, 8 months ago by syncophono.
By using inheritance, there is no need to use global variables. The time remaining would be a protected attribute of the GameNameGameState class accessible to all the minigames.
There isn’t really a difference between:
globals.time
and self.time.
Plus, self.time indicates multiple time variables (one per minigame), when in reality we only need one time variable that is applied to all minigames. A global variable makes more sense here because the one parameter would affect everything.
To avoid those problems, and maybe others, but at the same time to achieve the desired effect, modern game engines pass to the update methods a deltaTime argument that can be scaled by the programmer. That way the simulation is not dependent on the game’s performance, the scaling can be non linear and async processes are not affected. The VUEngine’s GameState’s execute method passes such a value to the game objects, but it is only used to affect animations (that is, the engine’s classes only use the time delta to affect the animations’ speed, but derived classes specific to each minigame could use the time delta for other purposes), while things like physics simulations are updated by another facility.
Speed scaling can be implemented in a GameNameGameState class from which all minigames inherit. In this way, the “primary game” doesn’t need to exist, since it would just be logic shared by all minigames, achieving your goal of avoiding the need to reimplement on each one the same functionality.
I agree, delta time sounds like it would allow for a much more gradual speedup. Should we use fixed-point as the delta? I would imagine floats would be too slow.
if the game consists of say 50 minigames, increasing the speed in the way you suggest will be a nightmare to balance since the speed progressing from the first to the last will be too big.
The game won’t be running all 50 at a time, it just runs 1 at a time. You could have as many minigames as the memory allows, and performance will only matter at the level of the individual minigame code itself.