Ethan Mick
Ethan Mick

Reputation: 9567

How to have an "action" go off in the future in RoR?

Alright, this is a design question more than anything. I am making a text based game using Ruby on Rails 3, and I'm not sure the best way to implement what I want to do. In the game, the user gets a bunch of goblins, and can tell those goblins what to do. One of the available actions is attack, which as you can assume, means your tribe attacks something else, whether it be an opposing tribe, or a NPC settlement.

If you choose to attack an opposing tribe, then your goblins go off to attack. There is a set point when the battle will commence, (let's say, 10 minutes in the future). Here's the question, what's the best way to implement running the simulation for the battle in exactly 10 (or X) minutes in the future? Because if the simulation is run too soon or too late, then the entire outcome of the battle could be changed by what the opponent does.

(I know it's a little vague, but for those of you who have played Ogame, entire battle outcomes can change if the simulation is run a second too soon or late.)

I was looking at ways to implement having something run at X time in the future (this episode, and the two previous), but it doesn't seem to be tuned toward something that needs to be run precisely at time X. I also looked in to Ruby timers, but there doesn't seem to be a consistent one, like there is in java, nor do they automatically make the data persistent. I was hoping for low coupling too, perhaps using the observer pattern.

So there you have it. If I send my attack, or want to do anything at exactly time X in the future, what's the best way to do this in Ruby on Rails?

Upvotes: 0

Views: 183

Answers (2)

Kalendae
Kalendae

Reputation: 2244

The typical thing to do if you want some event to happen in the future with ruby on rails is to use cron to fire externally (as simon suggested) or use the delayed_job gem and set a job for the future. You can also use rufus-scheduler gem like this:

scheduler.in '10m' do
    puts "something happening 10 minutes from now"
end

Upvotes: 0

Simon Woker
Simon Woker

Reputation: 5034

Simple answer: Don't

You should save the time (now+10 minutes) in a database and then run a cronjob every minute (or whatever you prefer). This should then evaluate all fights that should be fought at that time. For best practices on this behaviour see A cron job for rails: best practices?

You could also add a check if a fight can be fought on every request you get. This way you'll get a little bit more randomness when the fight will start exactly and depending on the traffic of your site, this could be like every second. Remember to start a thread to evaluate the fight, depending on the amount of your calculations. Otherwise some users can experience massive lags.

Upvotes: 2

Related Questions