Page 1 of 1

Asking some ideas for a small game, "Propulsion"

Posted: Sun Nov 25, 2012 12:57 am
by ChOwW
Hi people!

After working 2/3 loooong days on my personnal engine, I would like to chill up a little more, making a small but simple project that I'm working on.

The mod is called "propulsion". As you may have understood, it is a small game where propulsing yourself is the key to end levels.

I would like to present you the project in order to see what could be interesting, or not.
Take care that the mod itself would use all buttons for the PSP aswell as the Wii. (and the PC could of course use those buttons, but it only uses 6 buttons, so...

=======
Propulsion
A Small puzzle game - Created by Ch0wW
=======

What is the main goal?
-------
In Propulsion, you are given some weapons that are making you propulsing, to solve some puzzles. It may be adapted from Portal for its simplicity, but the game is absolutely different.

Weapons :
--------
- Propulsor (DONE) :
* A simple weapon that propulses you once you're on the ground.
* Firing speed : 0.75 (0.65 if trying to shoot in mid-air).
* Can gain velocity with a good timing ( current velocity / 2 + ( 0 0 450) )

- Dual Propulsor (NEARLY DONE) :
* A small upgrade to the propulsor, used to have another propulsion in mid-air.
* Firing speed : 0.50 ( 1 second if trying to shoot after the second shot in mid-air)
* Cannot gain velocity. In fact, your velocity decreases by 25% after shooting once, avoiding to speedrun too easily the level)

- BodyHook (NOT DONE + NAME TO CHANGE ) :
* A Small grappling hook that can teleport you if they're hitting a special texture/entity (don't know if possible)
* Firing speed : 1.5 second once the "projectile" has "disappeared" (life end / touch something).
* The projectile is up to 2 seconds, at a speed of 300units.
* If it hits an allowed entity, teleport there.


Gamemodes :
---------
- Story mode : The story (NO STORYLINE ATM)
* Has 3 difficulty levels :
x Easy mode, where you can move your character
x Hard mode, where propulsing yourself is the only way to move your character, adding difficulty, and more reflexion.
x Crazy?! mode, where your propulsions are actually backwards (like the gauss-effect on HL1)
* Saving is not allowed, except in the beginning of each level (automatic save).

- Thoughtmore mode (NEARLY DONE): A mode where finishing a level with the minimum amount of propulsions is the key.
* Played in Hard difficulty, unlocked once 2 levels has been done.

- Time trial (NEARLY DONE): A mode where finishing a level must be done the quickest as possible.
* Auto-Recording will be set to 1 (except if a cvar is set (g_timetrial_noautorecord , mostly for PSP / WII users)
* played on hard difficulty
* Will be a local ranking

- EaS-core (= Hi-Score): A mode where you have to collect easter eggs that are hard to reach quickly in order to get the best score.
* Unlockable once the story has been finished on Hard difficulty
* Will be done on special levels.
* Eggs + Time to finish the level = Score

Movement :
----------
- There is no jumping.
- After landing, there will be a little friction. (AMOUNT UNKNOWN)
- There will be ice, increasing again friction.
- There will be water (CAREFUL, WE MUST NOT SWIM) , reducing the propulsion effect by 15%.

- Moving can be done only on easy difficulty

Camera :
-----------
- After pressing A (Wii) or LTRIGGER (PSP) or [insert binding] (PC) the camera will switch to Free-Look mode.
* THERE IS STILL CLIPPING !!
* Once switching camera mode, we must leave the character in position, with his current angle.
* moving is allowed, even on hard mode, of course
- Pressing the button again will revert to the player's pov.

Mapping :
------------
- No ideas, but must be simple with different environments
- Removing BodyHook / Dual propulsors on each end of level
- can be traps (ex: walls crusing the player), but we musn't be too violent (game could be played for young people, and must have no blood)

That's all I have found after a small brainstorming.
Well, how do you find this game's idea?

Re: Asking some ideas for a small game, "Propulsion"

Posted: Sun Nov 25, 2012 2:24 am
by gnounc
I didnt read anything that isnt possible in a quake engine.
The checking for textures bit would require fte or darkplaces, but if you are going to be mapping for it anyways, you could
just put a brush there instead.

The mod itself sounds fun, I dont have any suggestions for you yet, but
when you are further along something might come to mind.

Best of luck.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Sun Nov 25, 2012 1:36 pm
by ChOwW
Thanks about the textures fact gnounc!

Well, I could have another way, to use some funcs (func_freeze, or func_ice for exemple to change instantly friction for exemple...) , that shouldn't be really hard (except maybe for func_bodyhook_target, who knows if it could work?...)

Anyway, most of the features I've written are already implanted at the moment, as well as a very small testing map (I'm not good at all about mapping however, so only 2 textures are in the whole map ahah)...

After my hackathon & gamathon events (I'll present Projection for the gamathon), I'll probably post some videos, as well as my source codes (where you'll see a GLQuake engine totally stripped down, will be fun :) )...

Re: Asking some ideas for a small game, "Propulsion"

Posted: Mon Nov 26, 2012 12:19 am
by mankrip
The concept reminded me of RocketBoy2. I couldn't find any screenshot or video of it, but you can play it in in a J2ME emulator or in a phone. This game is really fun and simple, it may give you some ideas.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Mon Nov 26, 2012 4:22 pm
by Spirit
Baker has something for texture identification. I remember he posted about some developer options where you could get the engine to tell you what texture was behind the crosshair. I assume it would be in Proquake, but it might have been one of the many smaller coding experiments he did. Should be somewhere in these forums.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Mon Nov 26, 2012 4:26 pm
by ChOwW
I have tried it right now, and I must say it sure is simple and really fun, indeed!

Now I'm cleaning a bit my personnal mess (as well as the Quake 1.06 Progs).
But there is a small question I'm asking:

How could I make a special freecam?

I mean, here is the steps I'm trying to do:
1) If I press "Jump", I switch between My own POV and the Freecam Pov.

If I am in FreeCam Pov :
a) Render the player model and position, but don't make it move!
b) in this mode, move freely (can be done, will force cvars)
c) When I'll press "Jump" again, I'll be back in my own PoV like before. (and if I switch back, set me back where I left my Freecam)

I've tried to use that with the intermission code, but my player model disappears, and I am unable to move, even if I modify some moving flags...

Have something have an idea of what I could do?

Re: Asking some ideas for a small game, "Propulsion"

Posted: Mon Nov 26, 2012 6:02 pm
by mankrip
I usually separate the client entity from the player entity, and also use a third entity for the camera. This way, you can code the player's behavior explicitly, rather than having to restrict it.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Tue Nov 27, 2012 9:23 am
by ChOwW
Hum, that is difficult to put it in place...

I've tried some things by myself with entities, but it doesn't work...

But, if I'm understanding well, I should make two new entities (.entity player; , and .entity camera; ) ; replace every occurence in client.qc ;
Then, spawn a camera entity in PutClientInServer() ; and make the changes I need?

Re: Asking some ideas for a small game, "Propulsion"

Posted: Wed Nov 28, 2012 2:08 am
by ChOwW
After some hours of wondering how I could do it, I finally managed to make it! Thanks again mankrip, you gave me a great idea of how you can do it!

But after restricting weapons in freecam, I imagine it is really buggy, ahah...

anyway, I just have another problem. After saving my models, the main error is that I can't save properly my angles ... It is always set to where I am watching right now...

Here is the code :

Code: Select all

/*
=================================
G_Camera.qc
Camera class & view switchs
=================================
*/

.float fTimeSwitch;

//-------------------
//  CAMERA 
//-------------------
void() Camera_Init =
{
	self.cam = spawn();
	self.cam.classname = "info_camera";

	self.cam.takedamage = DAMAGE_NO;
	self.cam.solid		= SOLID_NOT;
	self.cam.movetype	= MOVETYPE_FLY;
	self.cam.deadflag	= DEAD_NO;
	
	self.cam.origin = self.origin + '0 0 1';
	self.cam.angles = self.angles;
	self.cam.fixangle = FALSE;

	setsize (self.cam, VEC_HULL_MIN, VEC_HULL_MAX);
	
	self.cam.view_ofs = '0 0 16';
	self.cam.velocity = '0 0 0';	

	dprint ("Camera spawned!\n");
};

void()	UpdateTo_Camera =
{
	self.takedamage = self.cam.takedamage;
	self.solid = self.cam.solid;
	self.movetype = self.cam.movetype;
	self.deadflag = self.cam.deadflag;
	
	self.angles = self.cam.angles;
	self.origin = self.cam.origin;
	self.cam.fixangle = FALSE;
}

//-------------------
//  PLAYER
//-------------------

void() PlayerPawn_Init =
{
	self.player = spawn();
	self.player.classname = "player";	// else, SV_Physics Fatal Error...
	setmodel (self.player, "models/player.mdl"); // (dirty hack) Make a model for the player:

	self.player.takedamage	= DAMAGE_AIM;
	self.player.solid		= SOLID_NOT;
	self.player.movetype	= MOVETYPE_FLY;
	self.player.deadflag		= DEAD_NO;

	self.player.origin = self.origin + '0 0 1';
	self.player.angles = self.angles;
	self.player.fixangle = TRUE;

	setsize (self.player, VEC_HULL_MIN, VEC_HULL_MAX);
	
	self.player.view_ofs = '0 0 16';
	self.player.velocity = '0 0 0';	
};

void() PlayerPawn_Update =
{
	self.takedamage = self.player.takedamage;

	self.solid = MOVETYPE_WALK;
	self.movetype = SOLID_SLIDEBOX;
	
	self.angles = self.player.angles;		// Error : Can't save my own angle!
	self.origin = self.player.origin;
	self.player.fixangle = TRUE;
};

void() Camera_SwitchView = 
{
	// Switch the view & behaviour to the camera
	if (self.bIsPlayer)
	{
		//--------------------------------
		// Backup first the player positions!
		self.player.origin = self.origin;
		self.player.angles = self.angles;
		self.player.fixangle = TRUE;
		setmodel (self.player, "models/player.mdl"); // (dirty hack) Make a model for the player:

		// Update Player to the camera
		UpdateTo_Camera();
		self.bIsPlayer = FALSE;
		bprint("View is Camera \n");
	}

	// Switch back to the player view.
	else
	{
		//--------------------------------
		// Backup first the camera positions!
		self.cam.origin = self.origin;
		self.cam.angles = self.angles;
		self.cam.fixangle = TRUE;
		setmodel (self.player, "");
		
		//--------------------------------
		// Set up the view model;
		PlayerPawn_Update();
		self.bIsPlayer = TRUE;
		bprint("View is Player \n");
	}

	W_SetCurrentAmmo(); // update weapon frames
	self.fTimeSwitch = time + 2;
};
Maybe it is my logic who failed this time... Coding at 3AM is nonsense...

Re: Asking some ideas for a small game, "Propulsion"

Posted: Wed Nov 28, 2012 3:06 am
by mankrip
The .angles and the .fixangle must be set every frame, preferably in PlayerPreThink (a more proper way to set the angles would be to use CSQC, but I haven't started learning that yet).

However, updating the origin works better in PlayerPostThink, due to being less prone to lags. I used to code two functions, one to update the angles and another to update the origin, and then call the function to update the angles from PlayerPreThink, and the function to update the origin from PlayerPostThink.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Fri Nov 30, 2012 3:47 pm
by ChOwW
Thanks for the hint ; although it does not fix the angles's position when I'm switching from the player to the camera, and vice-versa (problem: the camera's angles have the player's angles, even if I'm modifying angles).

Anyway, I've added some new triggers (with time trial), and added an ingame timer. Maybe there are some optimisations to do, but well, I don't care so much at the moment.

I've modified the progdefs.h file to link some elements.

Those who want the code is here :

[sbar.c]

Code: Select all

#include "quakedef.h"
#include "g_hud.h"

void	HUD_DrawPropulsions (void)
{
	char	str[80];	

	if (cl.gametype != GAME_PROPULESS)
		return;

	sprintf (str,"Propulsions : %i", (int)sv_player->v.iPropulsions);
	Sbar_DrawString (0, 0, str);
}

/*
==================
HUD_DrawGameTime
==================
*/
void	HUD_DrawGameTime (void)
{
	char	str[80];
	int		minutes, tens, units, milliunits, millicent, millitens;
	float	seconds;
		float gametime;

	if (cl.gametype != GAME_TIMETRIAL)
		return;
	
	if (!pr_global_struct->TT_TimeElapsed && !pr_global_struct->TT_FinalTime )
		return;

	if (pr_global_struct->TT_TimeElapsed)
		gametime = pr_global_struct->time - pr_global_struct->TT_TimeElapsed;
	else if (pr_global_struct->TT_FinalTime)
		gametime = pr_global_struct->TT_FinalTime;

	minutes = gametime / 60;				

	seconds = gametime - 60*minutes;		
	tens = seconds / 10;				
	units = seconds - 10*tens;			

	milliunits = (int)(seconds*1000) % 1000;
	millicent = milliunits/100;
	millitens = milliunits - (millicent *100);
	
	if (pr_global_struct->TT_TimeElapsed)
		sprintf (str,"Time: %3i : %i%i : %i%i", minutes, tens, units, millicent, millitens);
	else if (pr_global_struct->TT_FinalTime)
		sprintf (str,"Final Time: %3i : %i%i : %i%i", minutes, tens, units, millicent, millitens);

	Sbar_DrawString (0, 0, str);

}

[g_timetrial.qc]

Code: Select all

/*
=================================
G_Timetrial.qc
Gamemode done by having sv_gamemode set to 2.
=================================
*/

float bStartTime;

/*
================
info_timetrial_start
================
*/
void() info_timetrial_start_touch
{
		if (other.classname != "player")
		return;

		bStartTime = TRUE;
		TT_TimeElapsed = time;

};

void()	info_timetrial_start
{
InitTrigger();
	self.touch = info_timetrial_start_touch;

};

/*
================
info_timetrial_stop
================
*/
void() info_timetrial_stop_touch
{
		if (other.classname != "player")
		return;

		if (bStartTime)
		{
			TT_FinalTime = ( time - TT_TimeElapsed);
			TT_TimeElapsed = 0;
		}
		bStartTime = FALSE;
};

void()	info_timetrial_stop
{
InitTrigger();
	self.touch = info_timetrial_stop_touch;

};
Of course, there are no call of those functions (especially in sbar.c) so you have to link those to work ( Sbar_Draw (void) ) ...

Re: Asking some ideas for a small game, "Propulsion"

Posted: Fri Nov 30, 2012 7:55 pm
by mankrip
Hmm, I don't remember everything, and right now my QC code is in another computer.

The .angles field defines the external model's angles. The view angles are stored in .v_angle, and can be defined by using a SVC message:

Code: Select all

float SVC_SETANGLES = 10;

void SetViewAngle (vector v)
{
   msg_entity = self;

   WriteByte  (MSG_ONE, SVC_SETANGLES);
   WriteAngle (MSG_ONE, v_x);
   WriteAngle (MSG_ONE, v_y);
   WriteAngle (MSG_ONE, v_z);
}
You may need to do this on every frame.

Re: Asking some ideas for a small game, "Propulsion"

Posted: Fri Nov 30, 2012 8:59 pm
by ChOwW
Well, according to the piece of code you've provided, I only had to call this to update the v_angle both from the camera and the player (but still update the player's view with PrePlayerThink).

I always thought that "angles" were the view of the player, but not the angles from the model...
Now, I understand what was "v_angle" ... I should have been more cautious by its name...

Thanks mankrip anyway, that saved me from a lot of modifications!

(those who want to see the modifications : look below)

[client.qc, in PlayerPreThink : ]

Code: Select all

...
	if (self.view_ofs == '0 0 0')
		return;		// intermission or finale
	
	if (self.bIsPlayer)
	{
		self.player.angles = self.angles;
		self.savedPlayerAngles = self.v_angle;
	}
	else
		self.savedCameraAngles = self.v_angle;

	makevectors (self.angles);		// is this still used
...
[g_camera.qc]

Code: Select all

/*
=================================
G_Camera.qc
Camera class & view switchs
=================================
*/

.float		fTimeSwitch;
.vector		savedvelocity;
.vector		savedPlayerAngles;
.vector		savedCameraAngles;

void(vector v) SetViewAngle =
{
   msg_entity = self;

   WriteByte  (MSG_ONE, SVC_SETANGLES);
   WriteAngle (MSG_ONE, v_x);
   WriteAngle (MSG_ONE, v_y);
   WriteAngle (MSG_ONE, v_z);
}

//-------------------
//  CAMERA 
//-------------------
void() Camera_Init =
{
	self.cam = spawn();
	self.cam.classname = "info_camera";

	self.cam.takedamage = DAMAGE_NO;
	self.cam.solid		= SOLID_NOT;
	self.cam.movetype	= MOVETYPE_FLY;
	self.cam.deadflag	= DEAD_NO;
	
	self.cam.origin = self.origin + '0 0 1';
	self.cam.fixangle = FALSE;

	setsize (self.cam, VEC_HULL_MIN, VEC_HULL_MAX);
	
	self.cam.view_ofs = '0 0 16';
	self.cam.velocity = '0 0 0';	
};

void()	UpdateTo_Camera =
{
	self.takedamage = self.cam.takedamage;
	self.solid		= self.cam.solid;
	self.movetype	= self.cam.movetype;
	self.deadflag	= self.cam.deadflag;
	
	SetViewAngle(self.savedCameraAngles);		// [ANGLES] 
	self.origin		= self.cam.origin;
}

void() Debug_CamAngles =
{
/*	bprint ("Camera's v_angle : x=");
	bprint (ftos(self.cam.v_angle_x));
		bprint (" / y=");
	bprint (ftos(self.cam.v_angle_y));
		bprint (" / z=");
	bprint (ftos(self.cam.v_angle_z));
	bprint ("\n");*/
};

//-------------------
//  PLAYER
//-------------------

void() PlayerPawn_Init =
{
	self.player = spawn();
	self.player.classname = "player";	// else, SV_Physics Fatal Error...

	self.player.takedamage	= DAMAGE_AIM;
	self.player.solid		= SOLID_NOT;
	self.player.movetype	= MOVETYPE_FLY;	// else, SV_Physics Fatal Error too...
	self.player.deadflag	= DEAD_NO;

	self.player.origin = self.origin + '0 0 1';
	self.player.fixangle = TRUE;

	setsize (self.player, VEC_HULL_MIN, VEC_HULL_MAX);
	
	self.player.view_ofs = '0 0 16';
	self.player.velocity = '0 0 0';	
};

void() PlayerPawn_Update =
{
	self.takedamage = self.player.takedamage;

	self.solid = SOLID_SLIDEBOX;
	self.movetype = MOVETYPE_WALK;
	
	SetViewAngle(self.savedPlayerAngles);		// Error : Can't save my own angle!
	self.origin = self.player.origin;
	self.velocity = self.player.savedvelocity;	// To prevent a velocity-breaking bug
};

void() Debug_PlayerAngles =
{
	/*bprint ("Player's v_angle : x=");
	bprint (ftos(self.player.v_angle_x));
		bprint (" / y=");
	bprint (ftos(self.player.v_angle_y));
		bprint (" / z=");
	bprint (ftos(self.player.v_angle_z));
	bprint ("\n");*/
};

void() Camera_SwitchView = 
{
	// Switch the view & behaviour to the camera
	if (self.bIsPlayer)
	{	
		setmodel (self.player, "models/player.mdl"); // (dirty hack) Make a model for the player:
		UpdateTo_Camera();

		bprint("View is Camera \n");
		self.bIsPlayer = FALSE;
	}

	// Switch back to the player view.
	else
	{
		setmodel (self.player, "");
		PlayerPawn_Update();

		bprint("View is Player \n");
		self.bIsPlayer = TRUE;
	}

	W_SetCurrentAmmo();
	self.fTimeSwitch = time + 2;
};
Now, time to make a new progs function to see if we can beat our best times from an external file!

Re: Asking some ideas for a small game, "Propulsion"

Posted: Thu Dec 06, 2012 6:41 pm
by ChOwW
May I add some updates?

I've made what I wanted to do, a "time trial" mode.

Although it is relatively incomplete (and without any security checks, like a CRC in the record file to be sure the map has not been modified since), it is done, although I took much more time on the PSP. (the reason is that it never allowed me to update my scores)

The times are done through 2 triggers, one to start the timer, and another to stop it, and update the final scores (which has a bug : it displays "96"ms instead of "960"ms, making the scores wrong).

Also, I even started to add a new "trigger" , lowering your velocity, like if you were on ice. I've linked another element from the engine to the QC interpreter.
However, a main bug exists : I can't undo my friction after untouching the ice trigger... Also, I can't find a proper way to do it, anyone has an idea?

I think I'll give tomorrow a very small version of what I'm doing (even if it is ugly... GLQuake 'oblige' )...