Page 1 of 1

Scripted Enemies

PostPosted: Sun Apr 19, 2015 8:19 pm
by lulzaraptor
This isn't really a suggestion, but more of a "this feature can be expanded a couple different ways" so I figured this might be a place to post about it.

In the current build of the engine, you can define enemies with scripts. The initial idea was that you can replace/introduce new enemies into the engine by adding enemy scripts. (sample below) These would be global changes and would effect all maps (if replace was used). That concept didn't really sit well with me since it can make game-breaking scenarios. Especially if you needed a custom enemy for a custom level and then want to play the main game.

So here comes the suggestion part:
Enemy scripts should be defined on a per-level basis.

karb.js: show
Code: Select all
function makeKarb() {       
   var karb = new GenericEnemy(18, 45);  // enemy size   
   var idle = karb.createAnimation("idle", "enemies/carb/Karb 2 Idle");
   
   idle.setOnReset(function() {
      idle.setSpeed(0.5);
   });
   
   idle.setOnFrame(function(dt) {
      idle.setRotation(karb.getDirection().asDouble() * karb.getGroundAngle() * -0.5);
   });
   
   idle.addResetFrame(39);
   idle.flipHorizontally();
   
   var walk = karb.createAnimation("walk", "enemies/carb/Karb2Walk");
   
   walk.setOnReset(function() {
      walk.setSpeed(0.5);
   });
   
   walk.addAction(3, function() {
      var gain = 0.4 + Math.random() * 0.15;
      var pitch = 0.9 + Math.random() * 0.2;
      
      karb.playSfx("sfx/enemy/crab/try crab 2 footstep.ogg", gain, pitch);
   });
   
   walk.addAction(8, function() {
      var gain = 0.4 + Math.random() * 0.15;
      var pitch = 0.9 + Math.random() * 0.2;
      
      karb.playSfx("sfx/enemy/crab/try crab 3 footstep.ogg", gain, pitch);
   });
   
   walk.addResetFrame(11);
   walk.flipHorizontally();
   
   var patrolIdle = karb.createAIState("patrolIdle");
   var patrolIdle2 = karb.createAIState("patrolIdle2");
   var patrolWalk = karb.createAIState("patrolWalk");
   
   patrolIdle.setLife(60.0); // length of animation
   patrolIdle.setAIScript(function(current, dt) {
      if(current.isOver()) {
         karb.setDirection(karb.getDirection().getReverse());
         current.endState(patrolIdle2);
      }
   });
   
   patrolIdle2.setLife(60.0);
   patrolIdle2.setAIScript(function(current, dt) {
      current.onOverEndState(patrolWalk);
   });
   
   patrolWalk.setLife(90.0);
   patrolWalk.setAIScript(function(current, dt) {
      var acc = new Accelerator(0, 3);
      
      acc.set(karb.getForwardsVelocity());
      
      if(karb.isGrounded()) {
         acc.accelerateBy(dt, karb.getDirection().asDouble() * 0.15);
      }
      
      karb.setRelativeVelocities(acc.get(), karb.getDownwardsVelocity());
      
      if(current.isOver() || !karb.canMoveForward()) {
         current.endState(patrolIdle);
      }
   });
   
   karb.switchState("patrolIdle2");
   
   return karb;
}

registerLegacyEnemy(50, 'karb', 'new crab', makeKarb, 2); // overwrites old karb.
// new enemies should be defined with:
// 'registerEnemy([name], [desc], [constructor] [hp])'


bonus feature reveal: new engine uses javascript for scripting. Old scripting commands will be reinterpreted.
This also applies to the upcoming 'Ch3"

Re: Scripted Enemies

PostPosted: Mon Apr 20, 2015 1:32 pm
by Dtroid
cool

Re: Scripted Enemies

PostPosted: Tue May 19, 2015 3:11 am
by Dante
A shot in the dark, but what about some sort of API where a user can attach a compressed zip, sort of like a mod, and the only prerequisites be that it has it's own coded script and spritesheet, where the script calls from set files? That way making something like an archer or horseman(concept-wise) would be feasible. If the player is playing a level that requires this "mod", but it is not installed, the script would have a callback as to what mob to insert instead.

Probably overly complex, and could be watered down a whole lot, but maybe something to look into?

Re: Scripted Enemies

PostPosted: Wed May 20, 2015 9:32 pm
by lulzaraptor
"mods as zips" is something we've been working on. Currently you can extend nearly anything by zip injection.