What is possible in Trackmania 2 with Maniascript?

You can talk about ManiaScript for ManiaPlanet here

Moderator: English Moderator

Post Reply
xis101
Posts: 170
Joined: 15 Jun 2010, 15:28
Location: Franconie
Contact:

What is possible in Trackmania 2 with Maniascript?

Post by xis101 »

Hi all,

I'm no coder, but I am curious what is possible with ManiaScript in Trackmania (gamemodes - not map editor). We have already seen many gamemodes for SM made by users. Why isn´t there one in TM yet? Is there not enough info for coders? Can't it be done yet?

But my main question is:
What is possible in detail? What variables are there? (length of jump, length of drift, distance driven, etc.) ?
User avatar
TGYoshi
Posts: 795
Joined: 15 Mar 2011, 16:59

Re: What is possible in Trackmania 2 with Maniascript?

Post by TGYoshi »

xis101 wrote:Why isn´t there one in TM yet?
There is one, which I've made: Stunts. It basically finished the half-completed stunt mode of Nadeo.

There indeed is barely any information for scripters, but that's the same for SM. The big difference is that there are no samples for TM where scripters can start with, which I've made myself.

You can't do a lot, it's mainly match controlling. If you'd like to make a 1v1 mode you can make it so you drive after eachother, or round where everyone's spawning with 10 seconds delay between eachother, like done at time runs in cycling/skiing etc.

I can say it's very limited so far, but the libs are extending for TM. Recently stunt events were added which allowed me to finish the mode in ManiaScript so Stunts mode actually works.
But it's still very limited. Really.
=3
User avatar
jonthekiller
Translator
Translator
Posts: 4629
Joined: 15 Jun 2010, 11:07
Location: In Maniaplanet Alpha
Contact:

Re: What is possible in Trackmania 2 with Maniascript?

Post by jonthekiller »

It's more easy to make custom mode on a FPS than a race game.
Image
User avatar
TGYoshi
Posts: 795
Joined: 15 Mar 2011, 16:59

Re: What is possible in Trackmania 2 with Maniascript?

Post by TGYoshi »

Maybe, but it's a lot harder in TM as a lot is limited. You can't obtain car positions, as just ghosts are being sent around, etc.. A lot of things are also hardcoded.
A countdown race timer it's start time is derived from the map file by default, you can't set it manually. It's so limited.
=3
xis101
Posts: 170
Joined: 15 Jun 2010, 15:28
Location: Franconie
Contact:

Re: What is possible in Trackmania 2 with Maniascript?

Post by xis101 »

thanks for the answers. I hope there will be some updates of infos that can be read out.

Maybe someone from Nadeo can give us more infos? ;)
User avatar
BragonHightake
Posts: 250
Joined: 17 Aug 2011, 00:22

Re: What is possible in Trackmania 2 with Maniascript?

Post by BragonHightake »

What is with a Driftmode?
More speed=more points.
Possible?
User avatar
w1lla
Posts: 2287
Joined: 15 Jun 2010, 11:09
Location: Netherlands
Contact:

Re: What is possible in Trackmania 2 with Maniascript?

Post by w1lla »

Hi all,

After making some deliberate tests for a new Cupmode i am developing for TM2 where the BestRaceTime(in this case The driver who set a BestRaceTime during the race scores an extra point. So a Top1 player might get +1 if he beats the BestTime at that moment otherwise he will just get his points based on his finished rank at each round).

What can you do with the following maniascript for TM2:

Not much but some things are usefull ;)

- You can see which CP a player went through. (ex. CP: 0 = Start, everyother cp after start is +1.)
- You can see the Average Speed when a player goes through a CP. I haven't tested if you can do this every second but i think the memory of maniascript will be blown if you do so. (ex. 187.765) The Variable is an Real.
- You can see the Distance driven(ex. 986.531) Its a Real but it is 986 meters, 531 millimeter (I Suppose?!)
- You can See Damages but it always gives 0.0 (It seems deactivated some how) Its a Real.

An example Script can be found below which tells you all the Above in a log(); or in a Chatmessage. Just a reminder: it doesn't go to the next map automatic as its only an experiment script to test all the above.

Code: Select all

//*******************************/
//		TM Test Script			*/
//		Willem 'W1lla' Munckhof	*/
//		15-01-2012				*/
//*******************************/


#RequireContext CTmMode

#Include "TextLib" as TextLib
#Include "Libs/Nadeo/Mode.Script.txt"
#Include "Libs/Nadeo/TrackMania/TM.Script.txt" as TM

Boolean IsRaceBetter(CTmResult _Race1, CTmResult _Race2)
{
	declare Comp = _Race1.Compare(_Race2, CTmResult::ETmRaceResultCriteria::Time);
	return Comp > 0;
}		

// === Main ===
main() 
{
	UIManager.ResetAll();
	log("restart...");
	IndependantLaps = False;
	UiRounds = True;
	RespawnBehaviour = ::ETMRespawnBehaviour::Normal;

	// loop on the playlist
	while( !ServerShutdownRequested ) {
		UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
		 UIManager.UIAll.UILayers.clear();
		LoadMap();
		
		TM::Players_UnspawnAll();
		Scores_Clear();
		//  ============ Séquence d'intro:
		{
			sleep(0);	// flush loading lag.
			UIManager.UIAll.UILayers.clear();

	
			UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
			UIManager.UIAll.UISequence = CUIConfig::EUISequence::Intro;
			sleep(4000);	// HACK; should be "wait(sequences over)"
			
			UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
			UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
			foreach(Player, Players) {
				declare UI <=> UIManager.UI[Player];
				Player.RaceStartTime = Now + 100000;			// spawn the cars.
			}
			sleep(3000);
			
			UIManager.UIAll.BigMessage = "";
			UIManager.UIAll.StatusMessage = "";
		}
		

		// ============ Play the rounds until the ending condition is reached.:
		while( !MatchEndRequested && !ServerShutdownRequested ) {
			// Round initialization
		log("StartRound");
	UIManager.UIAll.UISequence = CUIConfig::EUISequence::Playing;
	CutOffTimeLimit = 0;
	TM::Players_SpawnAll(Now + 2000);
	foreach(Score, Scores) {
		Score.PrevRaceDeltaPoints = 0;
	}
	sleep(500);	
	Synchro_DoBarrier();

	declare RoundArrivalOrder = Integer[Ident];
	declare RoundArrivalOrderDirty = True; 
	declare MatchBestTime for Map = -1;
	
	
	declare NbContestants = Players.count;
	while(  PlayersRacing.count > 0) {
		TM::RunGame();
		TM::EndRaceSequence_Update();
		if (MatchEndRequested)
			return;

		// Process events queue
		foreach(Event, PendingEvents) {	
			PassOn(Event);
			
			//if (Event.Type == CTmModeEvent::EType::WayPoint) {
			declare Player <=> Event.Player;
			declare CPRace = Event.CheckpointInRace;
			log(Event.Speed);
			log(Event.Distance);
			log(Event.CheckpointInRace);
			log(Event.Damages);
			UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} Speed Through CP {{{Event.Speed}}}!""");
			UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} Distance Through CP {{{Event.Distance}}}!""");
			UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} CP no. {{{Event.CheckpointInRace}}}!""");
			UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} CP no. {{{Event.Damages}}}!""");
			
			declare Text r = TextLib::TimeToText(Event.RaceTime);
	declare Text b = TextLib::ToText(Event.RaceTime);
	r ^= "."^TextLib::SubString(b, TextLib::Length(b)-3, 3);
			//log(r);
			declare RaceTimePlayer = r;
			//log(Player.Login);
				
			//}
			
			
			if (Event.Type == CTmModeEvent::EType::WayPoint && Event.IsEndRace) {
				declare Player <=> Event.Player;
				
				assert(Player.CurRace.Time == Event.RaceTime);
				//log(Event.CheckpointInRace);
				Player.Score.PrevRace = Player.CurRace;
				if (IsRaceBetter(Player.CurRace, Player.Score.BestRace)) {
					Player.Score.BestRace = Player.CurRace;
					declare TimeText = "$o$EA2" ^ TextLib::TimeToText(Event.RaceTime, True);
					if (MatchBestTime == -1 || MatchBestTime > Event.RaceTime) {
						MatchBestTime = Event.RaceTime;
						declare Text r = TextLib::TimeToText(Event.RaceTime);
	declare Text b = TextLib::ToText(Event.RaceTime);
	r ^= "."^TextLib::SubString(b, TextLib::Length(b)-3, 3);
	declare RaceTimePlayer = r;
						TM::EndRaceSequence_Add(Player, TextLib::Compose(_("New match record! %1"), TimeText));
						UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} drove a new Match Record with a time of {{{RaceTimePlayer}}}!""");
				
					} else {
											declare Text r = TextLib::TimeToText(Event.RaceTime);
	declare Text b = TextLib::ToText(Event.RaceTime);
	r ^= "."^TextLib::SubString(b, TextLib::Length(b)-3, 3);
	declare RaceTimePlayer = r;
						TM::EndRaceSequence_Add(Player, TextLib::Compose(_("Personal record! %1"), TimeText));
						UIManager.UIAll.SendChat("""$fff{{{Player.User.Name}}} drove a new Personal record with a time of {{{RaceTimePlayer}}}!""");
					}
				} else {
					TM::EndRaceSequence_Add(Player, "");
				}
				
				assert(!RoundArrivalOrder.existskey(Player.Id));
				RoundArrivalOrder[Player.Id] = Event.RaceTime;
				RoundArrivalOrderDirty = True;
				if (CutOffTimeLimit == 0) {		// grace preiod for the others to finish
					CutOffTimeLimit = Now + 5000 + Map.TMObjective_GoldTime/6;
				}
			}
		}
		
		// Refresh score table.		
		if (RoundArrivalOrderDirty) {
			RoundArrivalOrderDirty = False;
			RoundArrivalOrder = RoundArrivalOrder.sort();
			
			declare Index = 0;
			
		}
		
		// end grace period if needed
		if (CutOffTimeLimit != 0 && Now > CutOffTimeLimit) {
			TM::Players_UnspawnAll();
		}
		
	}
	
	Synchro_DoBarrier();
	// endround sequence
	sleep(1000);
	UIManager.UIAll.UISequence = CUIConfig::EUISequence::EndRound;
	UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
	UIManager.UIAll.SmallScoreTableVisibility = CUIConfig::EVisibility::ForcedHidden;

	}

	sleep(2000);

	foreach(Score, Scores) {
		Score.Points += Score.PrevRaceDeltaPoints;
		Score.PrevRaceDeltaPoints = 0;
	}
	Scores_Sort(::ETmScoreSortOrder::TotalPoints);	

	sleep(2500);
	UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
	sleep(500);	
	Synchro_DoBarrier();
}
			declare BestScore = 0;
		
		// ============ Séquence de fin:
		TM::Players_UnspawnAll();
		
			UIManager.UIAll.UISequence = CUIConfig::EUISequence::Podium;
			sleep(2500);

			UIManager.UIAll.UILayers.clear();

			sleep(3000);
			UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
			sleep(5000);
		
		Synchro_DoBarrier();

		UIManager.UIAll.ScoreTableVisibility = CUIConfig::EVisibility::Normal;
		UIManager.UIAll.UILayers.clear();
		Scores_Clear();
		MatchEndRequested = False;		// taken into account.

		UnloadMap();
}
An Example of the Values i used can be found here:

http://tmrankings.com/maniascript/html/ ... event.html

If there are any questions dont hesitate to ask.

With kindly regards,

w1lla
TM² Info
SM Info
QM Info

OS: Windows 10 x64 Professional
MB: MSI 970A-G46
Processor: AMD FX-6300 3500 mHz
RAM Memory: 16 GB DDR3
Video: SAPPHIRE DUAL-X R9 280X 3GB GDDR5
KB: Logitech G510s
Mouse: Logitech G300s
Mode Creation
ManiaScript Docs
Post Reply

Return to “ManiaScript”

Who is online

Users browsing this forum: No registered users and 0 guests