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.) ?
What is possible in Trackmania 2 with Maniascript?
Moderator: English Moderator
Re: What is possible in Trackmania 2 with Maniascript?
There is one, which I've made: Stunts. It basically finished the half-completed stunt mode of Nadeo.xis101 wrote:Why isn´t there one in TM yet?
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
- jonthekiller
- Translator
- Posts: 4629
- Joined: 15 Jun 2010, 11:07
- Manialink: maniaolympics
- Location: In Maniaplanet Alpha
- Contact:
Re: What is possible in Trackmania 2 with Maniascript?
It's more easy to make custom mode on a FPS than a race game.
Re: What is possible in Trackmania 2 with Maniascript?
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.
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
Re: What is possible in Trackmania 2 with Maniascript?
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?
Maybe someone from Nadeo can give us more infos?

- BragonHightake
- Posts: 250
- Joined: 17 Aug 2011, 00:22
Re: What is possible in Trackmania 2 with Maniascript?
What is with a Driftmode?
More speed=more points.
Possible?
More speed=more points.
Possible?
- w1lla
- Posts: 2287
- Joined: 15 Jun 2010, 11:09
- Manialink: maniaplanetblog
- Location: Netherlands
- Contact:
Re: What is possible in Trackmania 2 with Maniascript?
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.
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
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();
}
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
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
Who is online
Users browsing this forum: No registered users and 2 guests