The matter of Time...how to make lua timers?

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
LordofKral
Posts: 27
Joined: Mon Feb 10, 2014 5:56 pm

The matter of Time...how to make lua timers?

Post by LordofKral »

Hi Guys,
Thankyou for helping.
I bit time ago, i have had an idea, to implement a "Ghost" into a Dungeon,
That means: A bunch of Sounds is played, when player does something or go somewhere, when he she it stuck in a part. The Sounds are a voice, of
Toorum or whatever, simply a ghost. But to make it more realistic, the voice have to wander around, Mbe one sentence is parted into 5 Sounds,
and every sound is played after the sound before on another cell, a 3D Experience...
But i don´t know how to script that in lua.script, when i let it play the sounds one after another the experience goes strange...they are all played together in a whispering, terrifying loud sound. XD
Can anyone help?
Thankyou very much

LordofKral

(I´m neither an Expert in Modeling nor in Editing, I´m just full of Ideas...)
(I hope you can all read that above, I know my english is partly cruel, but i´m German!) ;)
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: The matter of Time...how to make lua timers?

Post by DesperateGames »

First thing: The topic "how to make lua timers" lets me assume that you have not yet discovered the timer entities that you can place with the editor? If not, try them first, maybe this already solves your problem. ;)

If you have seen them already and are still having probelms: I can think of multiple ways on how to do this: The simple approach would be (if you have 6 different sound files, for example):

Put 5 Timer objects in the level, let's say "timer1" to "timer5". Set the interval on the timers so that they match the runtime of the sounds for example:

sound 1 runs 500 milliseconds -> Set timer1 to 500
sound 2 runs 384 milliseconde -> Set timer2 to 384

and so on.

Use a hidden pressure plate to play the first sound via script (playSoundAt() ) and to activate the first timer. The first timer then does the following after its runtime:

- it stops itself
- triggers a function that plays sound 2
- starts the next timer (timer2)

From there you can always continue like this, playing one sound after another at the desired time.

If you plan to do this very often in your dungeon and you have keen programming skills, you might consider something like a lua table where you store all the names of sounds, the required durations, and where they need to be played etc. Then you could write functions to start a sound sequence and to step through the desired sequence in the lua table by adapting the runtime of a single timer and playing the correct sounds. I hope you get the idea, but as this is more complicated, I can't type this down on the fly in the forums, I would need to fumble with this by myself until it would work. ;)
The second approach would be more programming, but it could save you time as you would not need to manually set up a lot of timers.
User avatar
Eleven Warrior
Posts: 745
Joined: Thu Apr 18, 2013 2:32 pm
Location: Australia

Re: The matter of Time...how to make lua timers?

Post by Eleven Warrior »

I am guessing here, but in the Mines of Malan Vael there is a script which plays random sounds on the level. The Mines Wallset can be downloaded from the nexus forum. The script is on level 1.
LordofKral
Posts: 27
Joined: Mon Feb 10, 2014 5:56 pm

Re: The matter of Time...how to make lua timers?

Post by LordofKral »

Thx to all.
Yes, i thought about a lua programm script, i don´t like 200 timers, wasting place on my map... XD
Mines of Malan Vael: I only played through, haven´t seen the editor yet, thanksyou for the tip, i think i gonna make some new windy effects or
mybe Birds....
User avatar
Diarmuid
Posts: 807
Joined: Thu Nov 22, 2012 6:59 am
Location: Montreal, Canada
Contact:

Re: The matter of Time...how to make lua timers?

Post by Diarmuid »

you can use jKos' LoG framework timers module, quite complete, which is an extended lua wrapper for Grimrock native timers.

otherwise, if you want a pure lua solution here's what we use in the ORRR2 as a global time system (complete sources will be coming up 2 weeks after initial release, which should happen next week):
SpoilerShow

Code: Select all

-- =======================================================
--                        TIME 
-- =======================================================

lastFrameTime = 0;
dt = 0;
coroutinesTable = {};

function updateDt()
	local t = getStatistic("play_time");
	dt = t - lastFrameTime;
	lastFrameTime = t;
end

function waitForSeconds(delay, funct, args, id)
	coroutinesTable[#coroutinesTable+1] = {delay, funct, args, false, 0, id};
end

function startCoroutine(delay, funct, args, id)
	table.insert(coroutinesTable, {delay, funct, args, true, 0, id});
end

function stopCoroutine(id)
	--print("stopCoroutine start", id)
	for i = #coroutinesTable, 1, -1 do
		local tId = coroutinesTable[i][6];
		if tId and tId == id then
			table.remove(coroutinesTable, i);
		end
	end
	--print("stopCoroutine end", id)
	
end

cTable = {};

function update()
	updateDt();
	if #coroutinesTable == 0 then return; end
	for i = #coroutinesTable, 1, -1 do
		cTable = coroutinesTable[i];
		if cTable then
			cTable[5] = cTable[5] + dt;
			if cTable[5] > cTable[1] then
				local result;
				if cTable[3] then
					result = cTable[2](unpack(cTable[3]));
				else
					result = cTable[2]();
				end
				if result == false or not(cTable[4]) then
					table.remove(coroutinesTable, i);
				else
					cTable[5] = 0;
				end
			end
		end
	end
end
put that into whatever script entity you want, like luaTime for example, send a call from the party onDrawGui hook to luaTime.updateDt().
Syntax is modeled after Unity3D:

use luaTime.waitForSeconds(delay, function, [args], [id]) to execute a function in n seconds delay. args is optional, it's the arguments to send to the funtion if it needs some, packed in a table (don't send game entities => serialization crashes). id is optional too, you can give the function call an id and use stopCoroutine(id) to stop the execution before it does.

startCoroutine has the same syntax, but the function will execute every n seconds forever, until you either return false from the function, or call stopCoroutine.

Ex usage from the orrr2, two coroutines to check achievements every 5s or manage monster respawning every 15 minutes:

Code: Select all

	startCoroutine(5, function() 
		orrrManager.checkSecretsAchievements() 
	end);
	startCoroutine(900, function() 
		crowSpawner.respawn() 
	end);
advantage is that this is always spot on in terms of time no matter where the party is, vs editor timers which slow down when not on the same level

example of a delayed call. here it`s for a secret you need to stand 10s on a particular square. the hidden pressure plate is connected on activate to startTimer and on deactivate to stopTimer (in the mod, the time functions reside in our orrrManager script:

Code: Select all

function startTimer()
	orrrManager.waitForSeconds(10, 
		function()
			temple_secret_door_4:open();
			secret_3:activate();
			teleporter_21:activate();
			timer_3:activate();
		end,
		{},
		"timerSecret")	
end

function stopTimer()
	orrrManager.stopCoroutine("timerSecret");
end
here, hope this gives you some ideas about how it can be done.
LordofKral
Posts: 27
Joined: Mon Feb 10, 2014 5:56 pm

Re: The matter of Time...how to make lua timers?

Post by LordofKral »

Yes, it definitly does ;)
Thank you very much!
Post Reply