Jump to content

R4bitF00t

Community Manager
  • Posts

    29
  • Joined

  • Last visited

About R4bitF00t

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

R4bitF00t's Achievements

Savage

Savage (3/34)

72

Reputation

  1. @The Master We do not have separate voice actors for map outcries vs. unit voicelines. It depends on the voice actors, if they fit and want to do the role offered. But most of the work is in voicing the new units at this time πŸ™‚
  2. @Lik hey, please write into our Technical Support Discord channel https://discord.com/channels/173414671678832640/594960603874066432 somebody will help you there πŸ™‚ @fShark hey, have you already completed the achievement in the previous years? all the rewards can be claimed only once per account
  3. @Rankerz yes, the description in-game is incorrect, the challenge requires The Soultree campaign map πŸ™‚ A fix has been introduced in a hotfix.
  4. Greetings Skylords! A new month; a new Community Update! It's time to bring you up to speed with everything going on in Skylords Reborn! Another packed community update! This time, we will take a quick look at the newly unlocked seasonal challenges, changes to the relic shop prices and a new shadow card reveal. We are also looking for new voice actors, so if you have ever wanted to immortalize yourself in a game, now's your chance! Before we get to the meat and bones of this community update, allow me a quick introduction. β€’ Something About Me Last month, we announced that our Community Updates have a new writer going forward. Let me properly introduce myself as your new Community Manager. I joined the Skylords Reborn team in 2021, after I read that without map developers, no new official maps would be made. I could not let that happen, and I joined as a Map Artist. That role slowly evolved into a Map Developer, and later also into an amateur Map Designer. I have worked to varying degrees on all released map content so far, and I actively work on new campaign maps and forge skins. I will keep my role in the map department in addition to this new title. So we can bring you new map content without any delays. Now, as a new community manager, it is my pleasure to celebrate this occasion by providing my first (mini)booster code for all of you! NEWS-HERI-FFIN-TOWN Trying to buy some goodwill right at the start, eh? The code is valid until the 1st of December. But enough about me, let's move on to more interesting things. β€’ Changes to Seasonal Shop Prices Now that our second season has begun and the rewards from the previous season are now available in the relic shop, we have received some feedback about the relic costs. Some players only missed the Promo Sunderer, or other major rewards, by a few points, but they still need to pay full-cost for these cosmetics in the shop. This hardly seems fair, so we will be prorating the item prices in the shop. What this means is that every item in the shop connected to a season (including the Promo) will be discounted by a percentage proportional to the amount of progress a player made in the reward track of that season. This progress will be based on how close a particular player got to receiving the Promo reward. E.g. If you earned 60% of the points in the Fire Season that it would take to unlock the Promo Sunderer, all Fire Season cosmetics you missed will cost 60% less, forever. This discount caps at 70% for all cosmetics, except the final title and the top 100 border reward, which caps at a 50% discount. This change affects all the current and future items in the seasonal shop that were a part of the seasonal rewards - profile cosmetics, titles, forge skins and promos. Players who have already purchased items from the shop for full price will be reimbursed for the relic price difference. We will introduce these changes in a small patch in the coming days. β€’ New Seasonal Challenges As the new month dawns, new seasonal challenges have been unlocked. Let's take a closer look at them now. 3.1 - Win different campaign maps or featured community maps on advanced difficulty or higher. No spell cards are allowed. All cards played must be Nature or Twilight cards. These restrictions apply to all team members. 3.2 - Win the 1-player featured community maps Nyxia and Aeglos Fortress on advanced difficulty or higher. All cards played must be Nature cards. 3.3 - Win the 1-player scenario The Treasure Fleet and the 4-player scenario The Guns of Lyr on advanced difficulty or higher. All enemy buildings in the map must be destroyed. All cards played must be Nature or Twilight cards. These restrictions apply to all team members. 3.4 - Win the 2-player scenarios Nightmare's Shard and Nightmare's End on standard difficulty or higher. Only cards of Tier 3 and below are allowed. All cards played must be Nature or Twilight cards. These restrictions apply to all team members. 3.5 - Win the 4-player scenarios Titans and Raven's End on standard difficulty or higher. No towers, fortresses, or shrines may be played. All cards played must be Nature, Twilight, or Neutral cards. These restrictions apply to all team members. 3.6 - Win the 1-player campaign scenario The Soultree on advanced difficulty or higher. No T2 cards may be used. All cards played must be Nature or Twilight cards. As usual, the challenges remain available until the end of the season. β€’ How Does It Work - Root Network Since this season's theme is Nature and Twilight, we thought it best to remind the players of a video explaining the root network - the unique and complex ability of the Nature faction. It can be tricky to understand and setup, but the pay-off is oftentimes very much worth it. β€’ Yearly Halloween Event The season of Halloween is upon us! That means the yearly time-exclusive achievements are back on the menu! Win the featured community PvE map Spooky Giants on expert difficulty to get Promo Jorne! The achievement is available until the 10th of November. Win the featured community PvE map Spooky Encounters on expert difficulty to get the Halloween Pumpkin profile picture and a Lost Souls booster pack! The achievement is available until the 4th of November. Please note, the rewards can be collected only once per account. β€’ New Card Reveal: Devourer Since we started releasing new cards in December 2021, every existing faction in the game has received at least one new addition to its roster with the exception of Shadow. This occurred mostly because other factions were in more dire need of new cards than Shadow, which was one of the most viable factions when the game was rereleased and which also had plentiful fodder for reworks like Plague, Altar of Nihil, and Infernal Chain. With the upcoming release of Devourer, the Shadow famine is at its end. Behold, the Devourer! Please note: We are still working on the card. While we are generally happy with it, numbers and effects might still change before release. Consume Consume one enemy unit in range. Devourer teleports to the target enemy unit’s location, instantly killing it. The consumed enemy is then resurrected as an own unit but dies after 30 seconds. Needs to have gathered 6000 life points from corpses first. Reusable every 40 seconds. Corpse Gathering Harvests energy from nearby corpses equal to their former maximum life points to enable the devouring of enemies. A maximum of 6000 life points can be stored at once. Mincemeat Allied units in a 20m radius around Devourer will explode as soon as they die, dealing 400 damage to hostile entities in a 15m radius, up to 600 in total. Effect can apply to a unit multiple times. Design notes: Devourer is a T4 pure XL unit. Pure Shadow's T4 is currently one of the least compelling options in the game and perhaps the weakest color combination right now. Other pure factions have major pay-off units in Forest Elder, Dreadnought, and Batariel, but Pure Shadow's own Shadow Worm is not on par with these options, and given its core design, it is not a good option to build a faction around. Enter Devourer. Devourer has synergy with two of Shadow's core mechanics, corpses and swarms. Once it has gathered enough life points, a Devourer can burrow through the ground and consume any non-boss enemy within a 30m range. That enemy is then resurrected as an allied unit for 30 seconds. Additionally, Devourer has a second mechanic where any allied unit that dies within a 20m radius will explode and deal damage to enemies. This directly synergizes with Consume and key Shadow support cards like Infect, Undead Army, and even Grim Bahir. With Devourer, players can destroy camps with combos like Infect + Frenetic Assault, then warp to a second camp where Devourer's Mincemeat mechanic will cause all the dying summons to explode and wipe the place out. We hope players will enjoy discovering all the combinations this upcoming addition to Shadow's T4 will enable. Devourer will release in an upcoming content patch, date to be announced. β€’ Art Spotlight: Devourer The Devourer artwork was created by our talented artist Spirit Alpha, with Elkondo coming in to do some finishing touches and color correction. Sketching As usual, we have started with a rough sketch of the Devourer's pose and design. That sketch was slowly improved upon with more details, a small pose adjustment and was finalised into a black and white image with a detailed background. Coloring During the coloring stage, we decided that the castle in the background was muddying the silhouette too much and removed it. We then adjusted the horns to better reflect the in-game model and via some texturing magic, made the shell appear more like a polished carapace. In the end, we increased the contrast of the entire image so that it better resembled the original card artworks. Finalizing In the final piece, we only made some small adjustments - like the smaller eye and added a thin fog effect to convey depth. The artwork sure evokes the feeling of the original game, and we hope you are as excited for the upcoming shadow card as we are! β€’ Voice Actors Search #3 Over the years, we've made several searches for new voice actors. While we have a stable roster of voice actors, we are looking to bring new blood into our fold and expand our range. If you are interested, please fill out this application form. We will send out a trial script with instructions to all the applicants within 4 - 6 weeks (depending on the number of applications), after which, our audio department will go through the submitted takes and decide on fitting candidates. β€’ Team Changes Majora left his post as the Community Manager, with me (R4bitF00t) being the successor. He will still retain his position as the Project Coordinator. We want to thank Majora for his years of Community Updates and dedication to the project and wish him the best in his new job! Rue has joined as a Trial Discord Moderator and quickly became an active member of the moderation team. Last month we released him from the role of Trial Discord Moderator and made him a full on Global Moderator. Congratulations, and good luck on your moderation journey! β€’ Contribute to Skylords Reborn Skylords Reborn is a community-driven project fueled by the passion and dedication of over 50 volunteers. We are always on the lookout for like-minded individuals. If you have a passion for gaming, programming, design, or marketing, we invite you to have a look at our open positions! [ Call for Help ] We are currently in need of more people to help us out with German translations. Don't have time to formally join the staff, but still would like to help out? Please check out this guide on how to support Skylords Reborn as a community member. β€’ Card Design Contest Winner Stream The popular Card Design Contest event has come to an end. We have had many great entries, and all that remains now is for the jury to review and rate all of the submissions. Be sure to join us on the 16th of November at 19:00 CET on Ultralord's Twitch Channel, where we will reveal the winning entries. β€’ Events In between our monthly Community Updates, we host various events and tournaments, so be sure to keep a close eye on the in-game event tab and the forum calendar to stay informed and not miss out on any exciting events! Current events: β€’ NEW - Happy Halloween! -> till 4.11.2025 Win the featured PvE community map Spooky Encounters on expert difficulty to get a themed profile picture and a Lost Souls booster pack! Reward is granted only once per account. β€’ NEW - Frankenstein's Monster -> till 10.11.2025 Win the featured PvE community map Spooky Giants on expert difficulty to get the Promo Jorne card! Reward is granted only once per account. Upcoming events: β€’ NEW - TEAM - Thrilling Epic Action Mission -> Start 14.11.2025 till 30.11.2025 Prepare yourself for an exciting 4 Player event - more information soon. β€’ NEW - Autumn Cup 2025 -> Start 09.11.2025 An exciting evening filled with PvP action! Register until 09.11.2025 to compete in 1v1 PvP matches with double elimination. The event starts on 09.11. at 15:30 CET, and will be streamed on Ultralord's Twitch Channel. <Click here for more details.> Recent events: β€’ FINISHED - Card Design Contest - Winner Reveal Stream on November 16th! For the second time, we have invited you to design your own cards and you sure delivered! Be sure to watch the event stream with the results on 16.11. at 19:00 CET on Ultralord's Twitch Channel. β€’ FINISHED - Rookie Tournament - Ended 19.10.2025 You can check out the event recording here. β€’ Host your own tournament / event Want to host a tournament or event? Please reach out to our Event Organizers @Metagross31 or @Ultralord. We can help you out with various topics and are glad to discuss potential ideas. We can also sponsor the prize pool for your event. If you have a cool idea for a PvE event, or want to host a PvP tournament, please don't hesitate to reach out to us; we will gladly assist you. β€’ In Conclusion That's all for this Community Update! We appreciate you taking the time to read through it. As is tradition, we're including a scratch code as a small token of our appreciation for your support. The code will reward you with a Twilight booster: TWIL-IGHT-BOOS-TNOW This code is valid until December 1st, when we will bring you another Community Update. We're always looking for ways to improve and value your feedback. If you have any questions, comments, or suggestions, please don't hesitate to share them with us. We'll be back next month with more updates on our ongoing projects and upcoming features. You can also sign-up to our e-mail newsletter here. Archive β€’ Skylords Reborn Documents (Deep Dives, Behind the Scenes, PvP Guide) β€’ Overview Community Updates β€’ Community Update October 2025
  5. Hey, so we have an official tutorial, the tutorial includes a chapter on setting up the scripting software, that includes pretty much all the script actions and conditions πŸ™‚ alternatively, here is the newest script reference wiki with all the commands https://skylords-reborn.fandom.com/wiki/Script_Documentation For card IDs, I'd search the forums, or you can use the Skylords Reborn map making discord - https://discord.gg/RZQbJPdA to ask for card IDs πŸ™‚ Somebody there probably has the file
  6. Thank you all for your kind comments, they mean a lot to me ^^ I'm already working out the second map's layout and mechanics, wish me luck 🀞
  7. Hello! Once you have completed your map, or at least got it to a functional state, you might want to publish the map to the community maps section of the campaign map. While BattleForge allows you to create almost any map you want, I just want to stress one thing - please make sure your map is playable without crashes, especially on loading. There is nothing that will discourage people more from trying your map, when it keeps crashing, or cannot even load properly. And just to make sure - please don't include anything offensive in your maps, be it vulgarisms or obscenities. With that out of the way, let's get to it! If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Publishing a Map Next Chapter β€’ Publishing a Map To make the map publicly visible, we need to return to the map editor. In the Map Settings -> Edit Map Description window, you can notice a little Public Map checkbox at the top. Simply check that, save and PAK the map. Only do this if you are ready to send your map out into the world. Make sure your map is playable before publishing publicly! Then, navigate to the community maps section of the campaign map (User Generated Maps). In the next window, search for your map, I will search for my "playable area test" map. The map should have a blue folder icon to the left of it - symbolizing the map is present locally on your machine. As you can see, the minimap is the beautiful one, we've made in the previous topic. Now you can press the Upload Map button to upload your map to the server. Once you upload it, you should see it in the list without any icon. If you forgot to set your map as public and upload it, you will see a crossed over eye icon to the left of it. You can hover your mouse over it to see what it means. This is to prevent accidental publishing of maps, or for you to see how the published map looks like before making it public. In that case, you will need to wait for the map to be deleted after the 3 hours, and then upload the map again - setting the map as public and uploading again immediately doesn't work. In the future, if for some reason you want to delete your map from the server, you need to contact a GM. β€’ Next Chapter Now you know how to publish your own map. I cannot wait to see what you come up with! I just hope you have read the scripting part of the tutorial if you don't know how, so the map actually does something 😁. So just in case, I will link you to the scripting part of the guide. For that, we will first need to set up a script editor. β€’ Script Editors β€’ Alternatively, return to the Map Editor Tutorial homepage here. β€’ Map Editor Tutorial β€’
  8. Hello again! You've seen me mention before, that you should generally choose larger map size than what you think you will need. That's because you can always make the playable area smaller, but not larger. Let's look at how we can adjust the visible and playable areas, and create a nice looking minimap for our maps. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Adjusting the Playable Area Creating a Basic Minimap Polishing the Minimap in Photopea Next Chapter β€’ Adjusting the Playable Area As mentioned before, the standard map size in BF is 512x512. This size is ideal for most of the maps, as the map is not too big or empty - too large maps can feel like a drag to play. You also want to reserve some space for the map border, as having the skybox visible is not exactly visually appealing. Remember that the average playtime of a BF map is around 20-30 minutes and 512 map is usually ideal for that. With that out of the way, let's see how you can make the playable area smaller. You can adjust the playable and visible areas in the Map Settings -> Edit Map Settings on the top hotbar. A window will pop up that has the values we need. You can see the border of playable and visible areas on the edge of the map, delineated by the red and blue lines. Red line is the playable area Blue line is the visible area By default, you will only see the red playable area line, as it is drawn over the blue visible area line, I've moved the playable area a bit so you can see both of the areas. The playable area serves an important purpose - it limits the area where you are able to play out cards and move your camera in the game. If you make it too large, and forget to block out the areas that should not be available on the map, players will be able to summon useless units outside of the intended map area, or worse - find exploits by skipping parts of the map. The playable area should cover ALL PARTS OF THE MAP THAT ARE ACCESSIBLE TO UNITS and be sure to reserve some free space on the sides. The visible area influences the in-game minimap preview and positioning. If the visible area doesn't match the player area, you will get weird minimap behaviour, like this. So generally, the visible area should match the playable area. Now, for the adjusting of these areas, there is not much to tell, you will need to play around with the numbers to adjust the areas to fit your map. (Your map doesn't need to be centered but it is a good practice.) I've created this really quick preview for my map - the green texture is my map layout, the dirt around it is the map edge - area where I don't want the player to be able to play out units, and in most cases even move them over that area. You can see the playable and visible areas are way out on the actual map edges where the terrain ends, I have highlighted my intended playable area in the yellow square. So now I need to play around with the settings in the Edit Map Settings window to match my actual areas to my preview. As you can see, it is a bit different from the preview, as I've tried to make the area more squared. You might have the black map border enabled. You can enable/disable that in the View -> Map Border. β€’ Creating a Basic Minimap When you think you have the areas correctly set up, you can check the minimap by using the Camera -> Create Minimap (experimental) option. Note that you need to have the map saved for this to be available. This will generate a very basic (and mostly ugly) minimap in the map's UI folder. If the visible area is roughly squared, you should be golden. While not perfect, this step is needed, as it gives us a great basis to continue working on our minimap in an image editing software. I personally recommend using Photopea - it is a free, browser-based image editing software, very similar to Photoshop. β€’ Polishing the Minimap in Photopea To make our minimap making easier, here is an image of the basic background that denotes the unplayable area - we will carve our playable area out of that. Right-click the image, and save it as. Here's a rar file of all the generic map backgrounds I could find. MinimapBackgrounds.rar I will import my generated minimap and this image into Photopea, with the minimap on a lower layer, and the unplayable area on a higher layer. Next, I need to match the size of the blocking layer to the minimap, so it covers the visible part of the image. Select the Blocking layer and press "V". Nodes will appear around our blocking image, grab the corner nodes and scale the image so it covers the visible part of our minimap image. Note - I've made the blocking layer slightly transparent so you can get a glipmse of the minimap underneath it. I will do an easy setup to be able to smartly delete the blocking according to the map shape. For that, you will need to select the Blocking layer and click this icon at the bottom, which will add a mask to the selected layer - a white square image will appear next to the layer preview. Now, you can click on the white square image, pick a black color for your brush and paint it on the canvas, you should see the blocking image disappearing while you paint. Awesome! Now, we just need to paint the black onto the mask so that we mask our map shape. To re-paint the blocking back, use white color instead of black. You can use the X key to quickly switch between your two selected colors. This looks pretty rough, but with polishing the borders more, adding some layer effects and boosting the colors of the minimap, we can get a pretty decent result in a couple of minutes. To add effects to a layer - double-click the layer (click away from the layer name), it will open up a window with all the effects available. For the blocking layer, I use an Outer Glow with Multiply blend mode - to give it a semblance of depth, and a Bevel and Emboss effect. I've also added a Brightness/Contrast adjustment layer above the minimap layer, but below the blocking layer. An adjustment layer affects all the layers below it, so like this, it increases the brightness of the minimap, while leaving the blocking layer as-is. If you want an adjustment layer to only affect the first layer below it, right-click the adjustment layer and check Clipping Mask. Now, all that's left is to replace the minimap in the map's UI folder. The map can be in the .jpg / .png / .bmp format, but be sure to only have one minimap in the folder. One final gripe I have with this minimap is that some parts of it are too close to the edge of the image. To fix that, I would need to adjust the playable and visible areas to be larger so I have more free space around the map, but alas, sometimes these things are a bit of a trial and error πŸ™‚ β€’ Next Chapter Just remember, stick with square shaped areas and you should be fine. To better flesh out the playable area, you will need the Blocking Tool. While the minimap creation can be daunting for an inexperienced person, I think with these basic principles anybody can create it pretty quickly. You can also use other adjustment layers, such as Hue/Saturation to adjust the colors of your layers - if you have a snowy map, it might be nice to desaturate the blocking layer so it is gray-ish/white-ish instead of green. In the next chapter, I will go over how to finally publish your map to the community map section. β€’ Publishing a Map β€’ Alternatively, return to the Map Editor Tutorial homepage here. β€’ Map Editor Tutorial β€’
  9. Hello once again! We are near the end of advanced scripting principles. Ifs and for loops are the last step between you and an official Skylords Reborn Advanced Scripting Degree! (jk) Let's look at them now, shall we? I will create two script files for this chapter, you can download them here. Don't forget to define the example.lua script in _scriptlist.lua! _globalvars.luaexample.lua If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content If, Elseif, Else For Loops Using Ifs in BF Scripts Using Loops in BF Scripts Next Chapter β€’ If, Elseif, Else First, I will use if, elseif and else conditions in a _globalvars.lua script. There, we can most easily see how to work with these conditions. In Lua, using the if condition is very simple. There are three basic keywords you need to know: if - starts the if condition block, is followed by the actual condition then - defines the actions that should happen if the condition is true end - closes the if condition block Let's look at the _globalvars.lua example above. I've declared a difficulty variable and used the GetDifficulty() function to get the difficulty we are playing the map on. The GetDifficulty() function returns the numbers 1, 2 or 3 based on the difficulty. 1 - standard difficulty 2 - advanced difficulty 3 - expert difficulty Then I use the if condition to check if the difficulty is equal to one of these numbers. To compare values, we use the following characters. == - checks if the value on the left is equal to the value on the right, be sure to use double = > - checks if the value on the left is bigger than the value on the right < - checks if the value on the left is smaller than the value on the right >= - checks if the value on the left is larger or equal to the value on the right <= - checks if the value on the left is smaller or equal to the value on the right As you can see, I've used the else keywords in the code. If you want to check another condition for the same if condition, use the following keywords. elseif - starts another if condition block, if the previous if conditions return false, is followed by the new condition to check needs the then keyword after the condition else - defines the actions that will happen if ALL the above ifs and elseifs return false, does not need then keyword In my example - if the difficulty is not standard, I use the ELSEIF condition to check if the difficulty is advanced. If the difficulty is not standard or advanced, then it must be expert, so I use the ELSE keyword - no further condition needed, as the ELSE actions get executed if all the other conditions fail. If you don't want to deal with the ELSE and ELSEIF keywords, you can separate the check into three separate IF conditions. Keep in mind that you then need to end every if condition with the end keyword. β€’ For Loops I am going to show you how to declare for loops outside of BF scripts at first. For loops are used to execute code multiple times, until you reach the loop count you specify. If you were to use for loops in general Lua scripts, you would go about it like this. So these are the keywords you need to remember. for - declares the for loop, is followed by definition how many times the loop should run do - defines the actions that should happen for every run of the loop end - ends the for loop After the for, we need to declare a variable for that loop, that we will increase by one every time the loop finishes, and the range the variable should start and end at. Like this. i = 1,2 This tells the loop to define the i variable that starts at the value of 1, and the loop will stop once the i reaches a value of 2. So the loop will run two times. first time when the loop starts at i = 1 second time when i = 2 the loop will not start a third time, as the i has reached the specified value of 2 This for loop would do absolutely nothing, but if we were to add an equation into the for loop... With this loop, it would increase our difficulty variable by 1 every time the loop runs. So in the end, if we started the map on standard difficulty, the difficulty variable would return 3 - as if we were playing expert, and it would return 5 if we were actually playing on expert. (GetDifficulty() returns 1 on standard difficulty and 3 on expert difficulty, then we add 1 for every loop -> 1+1+1 = 3 or 3+1+1 = 5 ) For now, let's just declare a variable number_of_spawners in _globalvars.lua. β€’ Using Ifs in BF Scripts To show you how to use ifs and loops in BF scripts, I am going to create an example.lua script. I want the game to give me an outcry that the script was successfully loaded, so I add a state (remember, every script needs at least one state) with a OnOneTimeEvent that sends out an outcry. Now if we define the example.lua into _scriptlist.lua, upon map start, we should get the outcry "EXAMPLE LOADED". To actually use the ifs and for loops in the script, we will need to define them OUTSIDE OF ANY STATE. The events we declare in ifs and for loops will be added to the next state after them. I've added an if difficulty == 3 condition above my INIT state. This condition will use the difficulty variable I've declared in _globalvars.lua and check if we are playing on expert difficulty. If the condition is true, it will add the declared OnOneTimeEvent to the INIT state below the if condition. You probably didn't notice this, but I've added something special to the MissionOutcry. A "..difficulty" after the outcry text. Believe it or not, but we can actually use the variables in BF actions and conditions. The double dot (..) tells the script to add whatever comes after the double dot to the text before it. In our case, it will add the difficulty variable to the outcry text, like this. Awesome! Also notice that the event will switch the script to the EXPERT state via the GotoState. Note that, it is important in the following topic. β€’ Using Loops in BF Scripts I've prepared a little scenario to showcase the usage of for loops. I have two fire spawners, one tagged spawn_point1 and the other spawn_point2. I want to spawn a squad next to each of them on expert difficulty. To do that, I will add the EXPERT state, to which the if condition from before switches to. And above the EXPERT state, I will define my for loop. I have two spawners, and I want to spawn one squad next to each of them. So I will declare the i = 1,2. I use the SquadSpawn action to spawn the squad and in the TargetTag, I use the good old double dot (..) to spawn the squad next to each spawner. The SquadSpawn action takes the "spawn_point" tag we specified and the for loop adds the number of the i after it. So what this for loop does is, it adds two OnOneTimeEvents with the SquadSpawn action to the EXPERT state. And the TargetTag for the first event is spawn_point1 and for the second event it is spawn_point2. Now, the number of spawners I have on the map can change as I work further on the map, for easy access to the number of spawners, I have declared the number_of_spawners variable in _globalvars.lua. We can use that variable in our for loop, now we won't need to sift through all the scripts to adjust the number of spawners we have, we can only change the variable in _globalvars.lua. Let's check our script in game. When we start the map on standard or advanced difficulty, the squads will not spawn. The EXAMPLE LOADED outcry tells us that the script works as it should, we just didn't select the expert difficulty. But when we start the map on expert (remember - we switch to the EXPERT state in our event in the first if condition), we will get a squad of Sunstriders next to each spawner, alongside the DIFFICULTY 3 outcry. YAY! Before we leave thic topic behind us, I just want to reiterate that the contents of the ifs and for loops get added to the next state that comes after them. β€’ Next Chapter I know this chapter was a bit... ify. But you successfully got through the advanced scripting principles. Don't worry, a bit of practice and some help from your fellow map making skylords will carry you a long way. In the next chapter, we will look at the very complex topic of Warfare Patterns. Using them can be really great and easy if you know what you're doing, but they include some weird behaviours that might confuse you. Don't dread, I will be there to guide you on your Warfare Pattern jouney to victory. β€’ Warfare Patterns β€’ (Coming Soon)
  10. Hello again! As I have investigated some scripts by the original BattleForge developers, I have stumbled upon template scripts! These templates are used when you want multiple scripts to have the same functionality, but with different targets, spawnpoints, respawn times etc. You define one template and use it in multiple scripts, in which you only need to declare the specified arguments. This can prevent mistakes that can happen when you copy-paste the same code multiple times, and forget to adjust the values, or introduce some typos. Here are the scripts I will create in this tutorial. spawn_template.luaspawn2.luaspawn1.lua If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Creating a Template Script Passing Arguments Using a Template Homepage β€’ Creating a Template Script I will create a simple script as a template to show you an example. I will create a script called spawn_template.lua (it is always best to include the "template" in the name of your template scripts). In the template script, we need to declare a function - I've called it "SpawnTemplate". A function needs to have the () brackets after its name is declared (I will tell you what these brackets are for in a little while). And we end the function with the end keyword after the closing curly bracket. Inside the function, I have created two states, each with one event. I want the script to be inactive at the start, and spawn a squad of thugs, once it is activated. And, this is it, this is a template script. It is very basic mind you, it does only one thing and with all the same parameters, so it is not very useful at the moment, we might as well have written this into a standard script. Now, let's have a look at how we can make this script actually usable... β€’ Passing Arguments We can pass arguments to the function, that we can then use in the code! For that, we need to tell the function to expect some arguments first. We do that by writing something in the function's () brackets - I chose args (for arguments), but you can write whatever you want in there, just name it something sensible. Now, in our code, we can specify which arguments the function will expect. We can do that by writing args.ArgumentName for the arguments we want to pass to the function, like this. I have added arguments for the map flag that activates the spawning, the tag of the spawn building which needs to be alive, and the target tag, where to spawn our squad of thugs. Now the code is actually reusable! Let's look at how we can do that. β€’ Using a Template I will create two scripts - the spawn1.lua and spawn2.lua. So my script1 folder looks like this. In these scripts, we only need to type the name of our template function, and pass it all the arguments we've specified in the template script, separated by a comma - In my case, the ActivateFlag, SpawnerTag and SpawnpointTag. You need to write these arguments between curly brackets {}, otherwise you will get an error. These are my arguments for spawn1.lua and spawn2.lua. Now, obviously our template is very simple, and copy-pasting it into multiple scripts wouldn't be much of an issue, but when you have more complex behaviour that is used in multiple scripts, having a template can really save your time, as you only need to truly debug the template script. At last, I will add the spawn1.lua and spawn2.lua scripts into _scriptlist.lua, as they don't share the name with a tagged entity, or a script group. Now, if I were to activate my map flags, for example in the _main script, I will have a squad of thugs spawn on every spawnpoint I declared, if the tagged buildings are alive. β€’ Homepage You can return to the homepage here. β€’ Map Editor Tutorial Homepage β€’
  11. Hello there! We have went over quite a few scripting topics, and they just keep coming. In this chapter, we will look at which scripts the game loads by default, and how you can create your independent script, that is not tied to any tagged entity. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Default Scripts Tagged Entity or Script Group Scripts _main.lua _scriptgroups.lua _spawngroups.lua _globalvars.lua _scriptlist.lua Next Chapter β€’ Default Scripts BattleForge automatically loads some predetermined scripts when starting the map. I have named these scripts the default scripts. The scripts the game automatically loads are: scripts that are named after a tagged entity or a script group _main.lua - this is the main script of the map, as such, every map needs to have a _main.lua script _scriptgroups.lua - you define script groups in this file _spawngroups.lua - here, you define the waves for warfare patterns _globalvars.lua - you can have global LUA variables in this file, and reference them in any other script in your map _scriptlist.lua - here you can declare your own independent scripts, that are not tied to any entity β€’ Tagged Entity or Script Group Scripts BattleForge automatically detects scripts, that share the name with a tagged entity or a script group. For example: If you have an entity on the map tagged big_guy - you can create a script named big_guy.lua and it will automatically load upon map start. Same with script groups, if you have a script group named sg_small_guys, you can create a script named sg_small_guys.lua and it will be automatically loaded. These scripts have one downside, as they only work for as long as the entity / entities are alive. Once the entity is dead, and there is no OnRespawnEvent in the active state, the script will stop working. β€’ _main.lua As stated above, the _main.lua script is the main script of the map. You can script general functionality in this script as it is not tied to any entity on the map. In official development, this script is mostly used for implementing difficulties or starting global timers. β€’ _scriptgroups.lua We went over the _scriptgroups.lua file in the Script Groups, Script Areas and Script Paths chapter. We define our script groups in this file, and add any adjustments to script groups for different difficulties. Example of the script β€’ _spawngroups.lua _spawngroups.lua is used for warfare patterns. Warfare patterns are used to easily create waves of enemies, control them and have them respawn. We will dedicate a whole chapter to warfare patterns. β€’ _globalvars.lua Sometimes, you want to use the same value in multiple places in your script, or even in multiple scripts. You can either type the value manually everywhere, or you can declare it as a global variable - giving you access to the same value in all your scripts. We can do that through _globalvars.lua. Inside the script, you just need to name your variable and assign it a value, like this. Then, you can reference the global variables in any script. In my case - reference global_respawn_seconds to get a value of 20, or number_of_enemies to get a value of 5. _globalvars.lua makes it also very easy, if you want to change global variables based on difficulties. In my case - I can shorten the global respawn time and increase the number of enemies on higher difficulties. Here is the script, if you want to make use of this on your map. I will be covering ifs and loops in a separate chapter. _globalvars.lua β€’ _scriptlist.lua As stated above, scripts that are tied to entites on the map only work for as long as the entity is alive. While you can design around this, it is not ideal and after a while, you might have trouble finding specific events. In _scriptlist.lua you can declare "independent" scripts. You can name them whatever you like, and these scripts will execute their events regardless of any entity on the map. We can, for example, create a script called map_start.lua, where we will handle the setup of the map - outcries, objectives and fog of war. Then, create a win_lose.lua script, where we will handle all the victory and game over events. For the game to recognize these scripts, we need to declare them in the _scriptlist.lua - so we also need to create that. Inside the _scriptlist.lua, we need to return the names of our independent scripts, like this. We will return a list of the names of our scripts in parenthesis, with the .lua extension. The names are separated by commas. You can also write this into one line, I just like to separate them into multiple lines for better readability. Generally, you want to script all specific functionality into separate scripts for clarity. Having everything in the _main script can lead to a mess of hundreds, if not thousands of lines of code, and working with the script becomes very inconvenient. Compare that to separating the functionality into individual scripts like: boss_behaviour.lua, objectives.lua, main_gate_opening.lua etc. Each script having only a couple of events, that are all tied to a specific function. I think you can see the benefit of doing this. β€’ Next Chapter This might have been a bit complex. But these special scripts become essential as you start creating more intricate maps. The next chapter covers script group member scripts, which allow you to do some neat stuff with individuals inside a script group. β€’ Creating Member Scripts β€’
  12. Hello again! Script groups are a great tool for map makers. While they make referencing and scripting with multiple entities much easier, the script group, by default, is pretty rigid. You lose access to the individual units, or you need to create separate scripts for them, and take care that they do not clash with the script group's script. That's why the original devs implemented member scripts. These scripts offer you access to all the units inside a script group, and allow them to act almost as separate entities again, while preserving the ability to work with them as a group. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Setting Up a Script Group Member Script Usage Creating Member Scripts OnIdleGoHomeEvent Next Chapter β€’ Setting Up a Script Group Before we can make a member script, we of course need a script group to create it for. In our Map Editor Tutorial map, I've prepared these units and tagged them spawn_defender1 to spawn_defender6. I will create my script group through the _scriptgroups.lua file. But feel free to use the in-editor Script Group Editor. In the _scriptgroups.lua, I've created a group called sg_spawn_defenders and assigned the spawn defenders to it . Since I want these units to respawn, I will create a script named sg_spawn_defenders.lua and add an OnRespawnEvent. Now, the units will respawn. But with a small twist - they will only respawn once ALL of the units in the script group have died. While there is nothing inherently wrong with that, and this behaviour may be desired in some cases, we usually want our spawn defenders to be more responsive. This can also lead to exploits, such as leaving one of the units alive to prevent the respawn of the remaining defenders. As you might have guessed, we will remedy this by creating a member script. β€’ Member Script Usage Member scripts need some further setup, but when finished, they can offer vastly improved functionality and control over units in a script group. Before I get to the creation of member scripts, I will give you some examples what you can do with them. make squads in a script group respawn individually, instead of as a group make squads in a group return to their original placement after respawning make squads in a script group behave as individuals, instead of as a group - instead of copying the same script for multiple entities, you can just use a member script to have multiple units have the same behaviou β€’ Creating Member Scripts Creating the member script is extremely easy. We will just copy the sg_spawn_defenders.lua script, and rename the copy to sg_spawn_defenders_member.lua. Please note that you NEED to name the member script as scriptgroupname_member.lua. This lets the game know, that you have created a member script for that specific script group. You also NEED the script group's original script file. Now, when we have the member script created, we need to clean up the original script. Just open the script, and since we don't want this script to do anything, just leave in an empty state - you need to have a state in the script for the game to register it. And our member script will have the OnRespawnEvent inside it. With only these few steps, we have made it so that, the units in the script group will respawn as individuals, instead of having to wait for the rest of the group to die. β€’ OnIdleGoHomeEvent Maybe you've noticed, that in the official campaign maps, the respawned units will return to their starting positions, instead of just standing around the spawner. This is a great little detail that not only makes the camp feel more alive, and look more visually appealing when players try to destroy the camp again, it also preserves the camp defenders' strategic placement. Ideally, when designing a camp, you want to place the defenders in a strategic manner - ranged units in the back, melee units in the front, maybe have them defend a chokepoint. When the units don't return to their original starting positions, it can negatively impact the camp's balance. We can fix this issue by adding one more event into our member script - the OnIdleGoHomeEvent. This event simply tells the units to return to a "home" position when they are idle for some time. We can leave everything as-is, except the TargetTag parameter. This parameter tells us, where "home" is. We will set this to StartPos. The StartPos parameter references the entities original placement - as it was placed in the editor. This parameter only works in scripts, that are named after a tagged entity or a script group. And more importantly - also in member scripts. With this one extra event, that works almost from the box, we can see that the units will return to their originally designated positions upon respawning. In the end, you should end up with these scripts in your script1 folder. sg_spawn_defenders_member.luasg_spawn_defenders.lua_scriptgroups.lua β€’ Next Chapter This concludes the member scripts chapter. First of our advanced topics. Just remember that you can create a fun and interesting map without ever needing member scripts. They can help the map feel better to play but are in no way necessary. In the next chapter, we will look at how we can use actual LUA language in our scripts to save ourselves a lot of time. β€’ Using Ifs and Loops β€’
  13. Hello there! Working with goals properly needs some additional setup. Goals use an .xml file with it's own formatting and sctructure. Luckily, you only need to create the goal file once per map. Now, let's see about these goals. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Creating goals.xml Defining Goals Working with Goals Simple Objectives Timer Based Objectives Counter Based Objectives Next Chapter β€’ Creating goals.xml To work with goals, we first need to define them. We do that in an .xml file named goals. Create a text file in the map folder (outside of any of the other folders inside) and name it goals.xml. Now, we are ready to define our goals. β€’ Defining Goals I will give you an example goals.xml file, so you have a backup to fall back to. goals.xml Since I don't have the proper knowledge of .xml files, I will at least explain to you what the parameters do, to the best of my knowledge. Upon closer examination, you can see that, again, the file is divided into logical chunks. First line declares what version and encoding we use for the file - just copy this into every other goals.xml file you create. Then, we need a defined space to put our goals in. This space starts with <mapgoals> and ends with </mapgoals> and inside it, we define our goals. Same as with the <mapgoals>, the individual goals are defined between the <goal> and </goal> pointers. Inside the <goal> parenthesis, we can declare some additional parameters for our goal. The only parameter you truly need is the tag parameter. Without it, you cannot reference the goal in your scripts. The other parameters are optional. Let's look at them now. sortorder - defines the sort order of the objective, lower numbers will appear higher in the objective list timeleft_colorchange - when you use the goal as a timer, this defines when the timer will change color, signalling it is running out musictype - defines whether the timer will use special "time is running out" music, it is unconfirmed if this works positivetimer - defines whether the timer is positive - such as reinforcements arriving, or negative - such as enemies arriving, or map loss upon timer expiration goalletter - here you define which letter the goal will use in-game, this increases clarity targettag - references a tag, or a script group, the goal markers will appear over these entities on the minimap, with the set goalletter hint - I don't know what this does, never used it Then, inside the <goal> and </goal> area, we define the text that is displayed in the objective list for each language. Every line starts with <text language = "xx"> and ends with </text> with the goal text written between these. You need to define one language for each line - en, de, fr, ru, and write the objective text - in each language, if possible, but you can write everything in English if you don't speak the language. Now that we have set up the goals file, we will look at how you work with goals in scripts. β€’ Working with Goals Simple Objectives There are a lot of actions and conditions that work with goals. You can set any goal to be a simple objective, timer based objective, or a counter based objective. These are the basic actions used with objectives. MissionTaskSetActive - activates a goal as a simple objective - no timer, no counter MissionTaskSetFailed - fails a task, be it simple objective, timed objective, or counter based objective, also removes it from the objective list MissionTaskSetSolved - completes a task succesfully, be it simple, timed, or counter based, also removes it from the objective list MissionTaskRemove - removes a task from the objective list, without any message to the players You only need to use two parameters. The Player parameter and the TaskTag parameter. With the Player parameter, you declare which players are affected by the task - meaning you can have different tasks for different players. The TaskTag parameter references the tag, that you set for the goal in the goals.xml. The text of the objectives in the objective list is determined in the goals.xml file. So you don't need the Summary and Description parameters. Timer Based Objectives With timer based objectives, you use these actions. MissionTimerStart - starts a timed objective and makes it active in the objective list MissionTimerStop - stops a timed objective and removes it from the objective list MissionTimerPause - pauses a timer until MissionTimerResume is called MissionTimerResume - resumes a paused timer MissionTimerChange - changes the text of the timed objective, for text of another objective and keeps the remaining time You can use the same actions of MissionTaskSetFailed, MissionTaskSetSolved and MissionTaskRemove as you do with the basic objectives. Counter Based Objectives With counter based objectives, use these actions. MissionCounterShow - shows the objective in the objective list with a max value (such as 0/10) MissionCounterHide - hides the objective from the list MissionCounterSet - sets the counter to a given value MissionCounterIncrease - increases the objective counter by one MissionCounterDecrease - decreases the objective counter by one MissionCounterSetToHealthPercent - sets the counter to display percentual current health of a tagged entity - DOES NOT UPDATE AUTOMATICALLY, you will need to use, for example, an OnIntervalEvent where you will execute this action periodically As with the previous objective types, MissionTaskSetFailed, MissionTaskSetSolved and MissionTaskRemove work as you would expect. The MissionCounterSetToHealthPercent is a bit special. It doesn't update automatically, so you need ideally an OnIntervalEvent that calls this action periodically. You also need the MissionCounterShow action and set the MaxValue parameter to 100 (as 100% is full health). Here is an example of each of the different types of objectives. β€’ Next Chapter This concludes the Creating Goals chapter. In the next chapter, we will look at which scripts the game automatically loads, and how you can create your custom scripts, not tied to any entity. β€’ Default Script Files β€’
  14. Hello there! Scripting groups, paths and areas are extremely useful when creating maps, I would even go as far as to say that they are necessary in most cases. Now, it is time to see what these groups, areas and paths are all about. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Script Groups Creation in the Editor Creation in the _scriptgroups.lua Script Areas Script Paths Next Chapter β€’ Script Groups Let's start with the most important topic first. Script groups do what their name implies. They group individual tags under one, master tag. If you learn one thing from this chapter, let it be how to create script groups. You can use script groups in scripts the same way as you would normal tags. You can easily discern if a tag references a script group, because a script group's name starts with the prefix sg_. Naming conventions for script groups follow the same rules as tagging entities, with the addition that the name of the script group must start with the sg_ prefix. E.g. sg_fire_outpost_defenders. There are two ways of creating script groups. Through the editor, or through a script called _scriptgroups.lua. I would suggest you pick one of these and stick with it, combining them is not ideal for clarity. Let's look at both of them now. β€’ Creation in the Editor Creating script groups in the editor is very simple and super quick. In the beginning, this should be all you need. But as time goes on, and you get more experience, you will find that doing the groups in the editor is very rigid and prevents you from using some advanced coding practices. To create a script group in the editor, we need to open the Script Group Editor in Windows -> Script Group Editor. We will also need the Entity Properties window. We can create new script group by pressing the New button in the Script Group Editor. The group's properties will be shown in the Entity Properties window. That is where you can rename the script group. Let's name it sg_fire_spawn_defenders, this group will include our spawn_defenders from the previous chapter of the tutorial. (Remember, we need to put sg_ prefix at the start of the group name!) Now, we need to insert our spawn_defender1 and spawn_defender2 squads into the script group. At the bottom of the Script Group Editor, there is a search bar, you can start typing the tags there and the editor will automatically offer you autocompletions. Select the spawn_defender1 in the offered list and press enter to insert it into the group. Do the same for spawn_defender2. There is also a very helpful feature, that will highlight tags that are not on the map in red. This is very useful if you have decided to change the tags of entities, or delete them. β€’ Creation in the _scriptgroups.lua Creating script groups in the _scriptgroups.lua is a bit trickier, it actually requires you to follow some strict formatting. But in return, it gives you more flexibility when you need to adjust your script groups at runtime. The good thing is, once you've set up one _scriptgroups.lua, you can just copy it into other maps. To start defining our script groups, we first need to create _scriptgroups.lua, same as we would create any other script. Create the script in the script1 folder. Because of its complexity, I will give you an example _scriptgroups.lua, so you can fall back on it if anything goes wrong. _scriptgroups.lua The _scriptgroups file will return an array (think of an array as a list) of script groups to the game. Since the script groups themselves are arrays of tags, the _scriptgroups thus returns an array of arrays. This is just to confuse you, now to the example. Similar to a State, declare your script groups array - I've named mine "sgs" follow the name by the = sign and {} curly brackets. Like this. sgs = { } You will define your script groups inside the curly brackets. To create a script group, we define it the same way as our previous array - we name the script group and declare its contents (tags) between the curly brackets. Though in addition, we need to separate all the script groups by writing a comma "," after every closing bracket. sg_example1 = { "example_unit1", "example_unit2", "example_unit3", }, sg_example2 = { "example_unit4", "example_unit5", "example_unit6", }, At the bottom of the script, we just need to return our script groups array to the game. In my case, like this. return sgs You can probably see that writing dozens of script groups, each of them containing up to dozens of tags, is not exactly fast. Luckily, there is a function in Notepad++ that can make inserting tags easier, and that is Column Editor. I will just direct you to official Notepad++ tutorial on how to use that functionality. https://npp-user-manual.org/docs/editing/ I will cover creating difficulties in more detail in another tutorial. For the moment, you have the example script that includes adding entities into a script group on expert difficulty. β€’ Script Areas Script areas are mostly used to check if an entity is inside it, or not. You can access script areas via Windows -> Scripting Tool. You might need to check the View Scripting Areas checkbox to be able to see what you are doing. To place a script area, click the Place Point button. Then, click and drag to extend the area from point to point. After the first two points are placed, you can extend the area by clicking and dragging a new point from anywhere along the line between two points. You can add as many points as you want to an area. If you need to move the points, you can do that by clicking the Select button. To remove the points, click Remove Point button and click on the points you want to delete. To use the area in scripts, we need to tag it. We do that by using the Select mode, and double-clicking any of the points of an area. That will select the whole area, and give us the ability to tag the area through the Entity Properties window. If we go back to our _main.lua script from previous chapter, we could change the TargetTag of the PlayerSquadIsInRange check. With the area clearly defined, we don't need to measure or gauge the distance ourselves. I have also changed the range to default, which seems to work best with script areas. Like this. β€’ Script Paths The Scripting Tool also houses our next guest - scripting paths. You can place a script path the same way you do a script area, only with script paths, you extend the path by click-dragging a new point from the last point of the path. Select a script path by using the Select mode and double-clicking any of the points of the path. Scripting paths have some extra options in Entity Properties. Here, we have: Continuous - makes the path continuous, meaning if you send units along that path, they will patrol it indefinitely. Travel in Reverse - reverses the direction in which you placed the points, making units start from the last point placed. When you send units along the path, they will follow it as closely as possible. The units will first start walking towards the first point of the path, and from that, they will continue to the next point and etc. remember that units will walk to the first point placed, first. If the path is continous, the units will patrol the path indefinitely. Sending units on a script path uses a different action than SquadGoto. To send a single squad along a path, use SquadCheckpointGoto action. To send a group of units along a path, use SquadGroupCheckpointGoto action. As stated, units sent on a script path will follow the path as closely as possible. When sending a script group along a path with SquadGroupCheckpointGoto, the units will wait at each point of the path, until all the units from the group are present before continuing. This is extremely useful when sending attack waves. β€’ Next Chapter This is the end of three, very imporant topics. It wasn't as much fun as making units move around, but these three things are practically necessary for map creation. Now, goals in BattleForge are a bit unwieldy to work with, I will tell you all about it in the next chapter. β€’ Creating Goals β€’
  15. Welcome back! I hope you are properly refreshed and ready to get back into action. We will look into further actions and conditions we will need to complete our scenario. If you encounter any issues, don't hesitate to ask in Skylords Reborn Map Making Discord. β€’ Content Setting up the Scenario Pt.3 Scripting Pt.3 - Ambush Setting up the Scenario Pt.4 Scripting Pt.4 - Respawning Scripting Pt.5 - Victory and Loss Next Chapter β€’ Setting up the Scenario Pt.3 In the previous chapter, I mentioned a surprise to the south. Since the southern path only has one Firesworn, I want to add a little ambush when the player approaches that location. Put another marker near the southern cave and name it ambush_cave. We will also want to set up the next waypoint for our Goldwagon, further to the east. Tag it target_east. β€’ Scripting Pt.3 - Ambush Let's return to the _main script once again. Now, we need to script our cave ambush. For that we need another OnOneTimeEvent. (See how much you can get done with the simplest things.) And add PlayerSquadSpawn action to it. I want to spawn a Magma Spore - for that, I will need to know its ID. Squad ID can be found in the editor, in entity properties as Database ID. The actual ID starts with the first non-zero number after the initial number. I filled in the TargetTag, Player, SquadId and amount into the PlayerSquadSpawn action, and I am ready for testing. And our Magma Spore spawns as expected. (I have moved the cave location, so that the Spore aggroes to the approaching player units.) Finishing the Goldwagon movement is simple, we just need a OnOneTimeEvent, with a very similar condition as the first two, that sends the Goldwagon to the target_east position. β€’ Setting up the Scenario Pt.4 In the east, I want to have an enemy base with respawning defenders. So we need to set it up. Let's add a fire spawner building, and tag it fire_spawn. You can use any building for this, including towers, but keep in mind that players are used to which buildings are the spawners. I've placed a defensive tower and a squad of Sunstriders and a Wrecker to act as defenders of this fire outpost. Now we need to tag our squads so we can respawn them. You can either tag the units one by one manually, or you can select all the squads (Sunstriders and the Wrecker) and with both of them selected, tag them spawn_defender1 and hit enter. The units will automatically be tagged as spawn_defender1 and spawn_defender2. This is very useful, particularly with larger groups. Last thing I want to do is create our final waypoint in the east and tag it target_finish. Then, I added a Thunder Wagon to act as a final obstacle before the players can win the map. I tagged him final_challenge. Now we will look at how we can respawn the outpost defenders, and script the win and lose conditions for the map. β€’ Scripting Pt.4 - Respawning Respawning units can be done in several ways. The easiest and most correct way is through the OnRespawnEvent. You might remember that I noted that the OnRespawnEvent is a special event. That is because it needs to be inside a script, that shares the name with a tagged entity or a script group on the map (I will explain script groups later). So let's look into that. On our map, we have two squads in the fire outpost - spawn_defender1 and spawn_defender2. We need to create a script for each of them. Create a new text file in the script1 folder, and name the new file spawn_defender1.lua. BattleForge automatically detects scripts that have the same name as a tagged entity on the map -> we have an entity tagged spawn_defender1 on the map, so we can create spawn_defender1.lua script and the game will automatically load it. The game only loads some predetermined scripts that start with "_" - such as _main, _scriptgroups, _scriptlist and _spawngroups. You can have a script that isn't named after a tagged entity, in that case, you need to declare it in _scriptlist.lua, which we will look at in future chapters. Now, open the spawn_defender1.lua script, create a state in the script (name it whatever you want) and insert an OnRespawnEvent into that state via the snippets. Now we need to adjust some parameters and declare a condition for the respawn. StartDespawned - determines if the units vanish at the start of the map, so they can be respawned at a later time TargetTag - position where the unit will respawn, "StartPos" means the unit will respawn at the position it was placed in the editor RespawnDelayMinutes - delay in minutes before the unit respawns after death RespawnDelaySeconds - delay in second before the unit respawns after death HealthPercent - with how much health the unit should respawn We want our units to be at their positions at the start of the map, so we will set StartDespawned to false. The units should respawn at the location of the fire spawner, so set the TargetTag to fire_spawn. The respawn should take only a couple of seconds, so leave the RespawnDelayMinutes 0 and set RespawnDelaySeconds to 20. We want the units to be respawned at full health, so leave HealthPercent as it is. I will do some further cleanup to make the script more readable. I have deleted the OnDeathActions block, as I don't need anything to happen when the unit dies. I have also deleted the GotoState as it is not necessary. Now, the unit will respawn every 20 seconds after it died. We need to insert a condition, that only if the fire_spawn is still alive, the units should respawn, otherwise the units will respawn out of thin air. We declare such condition with BuildingIsAlive. Now, we have explicitly written that the squad will respawn only if the fire_spawn building has not been destroyed. Instead of creating a new script and writing all of this again, we can simply copy-paste the spawn_defender1.lua script, and rename it spawn_defender2.lua. This way, we have easily set up the other squad to respawn as well. β€’ Scripting Pt.5 - Victory and Loss There is only one last thing we need to script, and those are win and lose conditions. First, we need to create a simple event, that will send the Goldwagon to the final target. We have done this a couple of times now. Now let's do the lose condition. Obviously, since we have an escort mission, we want the player to lose if enemies destroy the Goldwagon. The players lose automatically if they lose all of their monuments, you don't need to script that. For the Goldwagon, we use a simple condition EntityIsDead. This condition is found in the Conditions-Negated snippet library, as it is the negative of condition EntityIsAlive. And game over is an action PlayerGameOver. You can ignore the TargetTag parameter. For the win condition, I want the players to win if the Goldwagon approaches the final marker AND the Thunder Wagon final_challenge has been killed. When we want to check if a tagged entity is in range of other tagged entity, we use EntityIsInRange. You can probably guess what is the condition for when the Thunder Wagon is dead. To win the game, we need to declare an action PlayerGameWon. Let's do something a little bit different. Since winning the game instantly upon the completion of our objectives is a bit anticlimactic, we will set the victory on a delay. We can do that with the OnOneTimeTimerEvent. Set the delay to 5 seconds, and try to estimate where you need to put the conditions and the victory action. Your event should look like this. If you got it right, great! If not, don't worry, I will explain. When the TimerStartConditions are met, the event will start its timer and TimerStartActions will trigger. Since we want to win AFTER the timer is elapsed, we need to write our victory action into TimerElapsedActions, which get triggered when the timer elapses and if the TimerElapsedConditions are met. Now, we just need to test everything in game and... The fire outpost defenders respawn as expected. And I was unable to best the Thunder Wagon guardian and lost my Goldwagon... Only on my second try did I get a win. The bright side is that, everything works! β€’ Next Chapter This concludes scripting basic events! With this knowledge, you should be able to create mechanically interesting, yet simple maps. Search through the available Actions and Conditions in the snippets or on the wiki. Try things out, experiment and soon you will be able to do amazing things in the editor. In the next chapter, I will go over some very, very useful information on how to create and work with script groups, script areas and script paths. β€’ Script Groups, Script Areas and Script Paths β€’
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Terms of Use