Star Wars: Clone Wars' Bad Batch Are Just The Ninja Turtles
It may have taken six years to happen, but Star Wars: The Clone Wars is finally back for its seventh and final season. As the show's creative team begins wrapping up a story that first began with the 2008 animated film, a new group of heroes is joining the foray for this Disney+ original series.
Warning: The following contains spoilers for the Season 7 premiere of Star Wars: The Clone Wars, entitled "The Bad Batch." If you haven't watched the episode yet, look away now.
Early in the episode, a new group of "defective clones" are introduced. They call themselves the Bad Batch and are essentially soldiers for hire when there is a mission that might be harder to pull off. What's interesting about the Bad Batch, though, is who they resemble. It might not be easy to see at the beginning, but once it's explained that these particular clones have "desirable mutations," it becomes clear.
Global Illumination describes several algorithms used to calculate non-direct lights in game engines. In Godot, it’s implemented using the GIProbe node, which can calculate emissive lights and secondary reflections, giving you more accurate lighting in your scene at the cost of performance. In this tutorial we will go step by step through the process of setting up a GIProbe. You can learn more in the video embedded below.
The first step for setting up global illumination is to go through the scene, select each model that will participate in the calculations and select Use in Baked Lighting in the Geometry Instance section.
Once you have your models set to participate, it’s time to create a GIProbe node. Add a new Node to the Scene (doesn’t matter who it is parented to) of type GIProbe.
Now size the GIProbe box using the red/pink control handles, so that it envelops your scene. You can have multiple GIProbes per scene and having them overlap serves no purpose.
Now with at least one light source in the scene, with GIProbe selected, click Bake GI Probe in the menubar.
This will calculate the indirect lights in your scene. You can also have a GIProbe calculate the effects of emissive lights in your scene. Emissive lights are lights that are projected from textures. In a SpatialMaterial you can turn emissive on in the Emission tab by selecting Enabled. Emission is the color of the light emitted, while energy is the strength of the energy emitted.
Emissive lights will only be shown after being baked by a GIProbe. Emissive lights cannot move without baking the scene again. You can cause a GIProbe to bake lights in code using the following code:
get_node("../GIProbe").bake()
This is an expensive operation and should not be performed lightly.
There are a couple of ways to control the quality of the lighting generated by a GIProbe. The first is by setting the Subdiv property in the GIProbe.
The higher the resolution, the better the results but more expensive the calculations. You can also change the quality of lighting in Project Settings by enabling High Quality in Voxel Cone Tracing.
Once again, this is a trade off between quality and performance. Finally I should point out that GIProbe only works with the OpenGL ES3 renderer, not in ES2. On ES2 you are instead stuck with traditional Light Baking, which takes less processing power, but produces inferior and less dynamic results.
Another thing to be aware of is dealing with the GIProbe inside the Godot Editor. The GIProbe, as shown above, is a giant green lattice, which can make viewing your scene somewhat difficulty. You may be tempted to hide the GIProbe like so:
Unfortunately this turns the GI off completely! If instead you want to hide the GIProbe in the viewport, you turn it off in the viewport menu. In the viewport, select View->Gizmoes->GIProbe.
This value is a toggle and controls ALL GIProbes in the scene.
You can learn more about Global Illumination and GI Probes in the video below.
Dota Underlords starts its first ‘real’ season next week
By Ian Boudreau21 Feb 2020
Dota Underlords will kick off its first non-beta season next week. Season One officially begins February 25, and with the start of the new season comes a brand new battlepass and associated rewards.
Some of those rewards include new board props, which you’ll be able to place on your Underlords board to customize your battlefield. If you’ve reached level 5 while playing the beta, you’ll get a special golden Ricky Ravenhook statue as a thank-you gift. Players who purchase the new battlepass will get a stone version of the statue (and Valve says that yes, you may have both).
While Valve is doing a soft reset for ranks for the new season, you’ll keep your ‘Major’ rank – that’s the one you see on the homescreen, like Outlaw, Smugger, and Boss. The exception here is for players who reached the rank of Lord of Whitespire, who will all get knocked back to Big Boss III.
You’ll also be able to keep your Path to Sunbreeze and Streets of Whitespire boards if you’ve unlocked them. The new season will include a new default board, plus five brand new boards you can unlock by leveling up your battlepass.
Dota Underlords has gone through a tonne of changes over the course of its “protopass” season, and at the beginning of the year it was looking at some pretty low player numbers – at least compared to where it had been at launch. Hopefully the new season will convince players to return to the game, and bring with it some stability as well.
Review: Twelve South Curve SE is a minimalist Mac stand
Review
By Andrew O’Hara Friday, February 21, 2020, 11:49 am PT (02:49 pm ET)
Twelve South’s newest pedestal for MacBook may look similar to the company’s previous Curve stand. It does, however, boast a new sleek white appearance that is a rarity among MacBook stands.
Twelve South Curve SE supporting a MacBook Air
The Twelve South Curve
Curve has been around for a number of years now. It is a sleeve, minimalistic laptop stand well-suited for any portable Mac. It is one curved piece of aluminum that contorts to a cradle on top for the Mac to rest in.
The idea is that by elevating your up, it puts it at a more ergonomic height for use. It also hikes it high enough to go next to a monitor and use two displays side by side without a substantial height disparity —monitor stand height depending, of course.
The Twelve South logo under the Curve
With the Mac perched up in the air, this also enables better cooling for the machine, allowing it to increase its performance. If the machine overheats, it has to clock down the processor, but by ensuring that the machine is well-ventilated, it won’t throttle unnecessarily. Don’t assume you are going to get a massive boost in performance just because you elevate your Mac, but it will ensure you get every ounce of performance from the machine.
Twelve South Curve SE from the top
Final touches for the Curve include silicone on the bottom so it doesn’t slide around the desk and silicone pads where the Mac is placed as well.
Curve SE
The original Curve launched with a matte black finish but the Curve SE brings a new colorway — matte white.
Twelve South Curve SE
Matte white fits into a lot of today’s styles and clean, minimal offices. Even Apple’s new Mac Pro accessories like the Magic Keyboard are being lightened up with a silver body and black keys rather than black on black.
It also matches Apple’s white Magic Trackpad, Magic Mouse, and all of Apple’s cables and adapters.
Should you buy the Curve SE
We dig the Curve SE stand for our Mac. If you have the desk space to run dual monitors, this is an elegant way to pull it off. The underside is also very open compared to just sticking your laptop on a stack of books which means that space can potentially be utilized by other desk peripherals.
The box for the Twelve South Curve SE
The stand isn’t designed to be typed on, but rather an external keyboard and mouse. This could be a downside for some, but for most use cases it should be fine.
Our machine often gets pushed while editing photos and videos so any additional performance we can squeeze out by keeping it as cool as possible is also a minimal benefit.
It does take up a rather large footprint when not in use and can’t exactly be tucked away, but otherwise stays sleek and unassuming.
Larry Wall’s Practical Extraction and Reporting Language (PERL) was originally developed in 1987 as a general-purpose Unix scripting language that borrowed features from C, sh, awk, sed, BASIC, and LISP. In the late 1990s, before PHP became more popular, PERL was commonly used for CGI scripting. PERL is still the go-to tool for many sysadmins who need something more powerful than sed or awk when writing complex parsing and automation scripts. It has a somewhat high learning curve due to its dense notation. But a recent survey indicates that PERL developers earn 54 per cent more than the average developer. So it may still be a worthwhile language to learn.
PERL is far too complex to cover in any significant detail in this magazine. But this short series of articles will attempt to demonstrate a few of the most basic features of the language so that you can get a sense of what the language is like and the kind of things it can do.
To try out the above program on your PC, you can copy-and-paste the above text into a plain text file and save and run it. The line numbers will have to be removed before the program will work. Of course, the command that one uses to perform that sort of textual extraction and reporting is perl.
Assuming that you have saved the above text to a file named game.txt, the following command can be used to strip the leading numbers from all the lines and write the modified version to a new file named game:
$ cat game.txt | perl -npe 's/...//' > game
The above command is a very small PERL script and it is an example of what is called a one-liner.
Now that the line numbers have been removed, the program can be run by entering the following command:
$ perl game
How it works
PERL is a procedural programming language. A program written in PERL consists of a series of commands that are executed sequentially. With few exceptions, most commands alter the state of the computer’s memory in some way.
Line 00 in the Tic-Tac-Toe program isn’t technically part of the PERL program and it can be omitted. It is called a shebang (the letter e is pronounced soft as it is in the word shell). The purpose of the shebang line is to tell the operating system what interpreter the remaining text should be processed with if one isn’t specified on the command line.
Line 02 isn’t strictly necessary for this program either. It makes available an advanced command named state. The state command creates a variable that can retain its value after it has gone out of scope. I’m using it here as a way to avoid declaring a global variable. It is considered good practice in computer programming to avoid using global variables where possible because they allow for action at a distance. If you didn’t follow all of that, don’t worry about it. It’s not important at this point.
PERL scopes, blocks and subroutines
Scope is a very important concept that one needs to be familiar with when reading and writing procedural programs. In PERL, scope is often delineated by a pair of curly brackets. Within the global scope, the above Tic-Tac-Toe program defines four sub-scopes on lines 15-21, 23-31, 33-35 and 37-54. The first three scopes are prefixed with subroutine declarations and the last scope is prefixed with the label PROMPT.
Scopes serve multiple purposes in programming languages. One purpose of a scope is to group a set of commands together as a unit so that they can be called repeatedly with a single command rather than having to repeat several lines of code each time in the program. Another purpose is to enhance the readability of the program by denoting a restricted area where the value of a variable can be updated.
Within the scope that is labeled PROMPT and defined on lines 37-54 of the above Tic-Tac-Toe program, a variable named mark is created using the my keyword (line 40). After it is created, it is assigned a value by calling the get_mark subroutine (line 47). Later, the put_mark subroutine is called (line 51) to change the value in the square that was chosen by the get_move subroutine on line 50.
Hopefully it is obvious that the mark that put_mark is setting is meant to be the same mark that get_mark retrieved earlier. As a programmer though, how do I know that the value of mark wasn’t changed when the get_move subroutine was called? This example program is small enough that every line can be examined to make that determination. But most programs are much larger than this example and having to know exactly what is going on at all points in the program’s execution can be overwhelming and error-prone. Because mark was created with the my keyword, its value can only be accessed and modified within the scope that it was created (or a sub-scope). It doesn’t matter what subroutines at parallel or higher scopes do; even if they change variables with the same name in their own scopes. This property of scopes — restricting the range of lines on which the value of a variable can be updated — improves the readability of the code by allowing the programmer to focus on a smaller section of the program without having to be concerned about what is happening elsewhere in the program.
Lines 04 and 05 define the MARKS and BOARD variables, respectively. Because they are not within any curly bracket pairing, they exist in the global scope. It is permissible to create constant variables in the global scope because they are read-only and therefore not subject to the action at a distance concern. In PERL, it is traditional to name constants in all upper case letters.
Notice that scopes can be nested such that variables defined in outer scopes can be accessed and modified from within inner scopes. This is why the MARKS and BOARD variables can be accessed within the get_mark subroutine and PROMPT block respectively — they are sub-scopes of the global scope.
The statements in the program are executed in order from top to bottom and left to right. Each statement is terminated with a semi-colon (;). The semi-colon can be omitted from the last statement in any scope and from after the last block of many statements that define the flow of the program such as sub, if and while.
In PERL nomenclature, scopes are called blocks. Scope is the more general term that is typically used in online references like Wikipedia, but the remainder of this article will use the more perlish term blocks.
The statements within the first three blocks are not immediately executed as the program is evaluated from top to bottom. Rather, they are associated with the subroutine name preceding the block. This is the function of the sub keyword — it associates a subroutine name with a block of statements so that they can be called as a unit elsewhere in the program. The three subroutines get_mark (lines 15-21), put_mark (lines 23-31), and get_move (lines 33-35) are called on lines 47, 51 and 50 respectively.
The PROMPT block is not associated with a subroutine definition or other flow-control statement, so the statements within it are immediately executed in sequence when the program is run.
PERL regular expressions
If there is one feature that is more central to PERL than any other it is regular expressions. Notice that in the example Tic-Tac-Toe program every block contains a =~ (or !~) operator followed by some text surrounded with forward slashes (/). The text within the forward slashes is called a regular expression and the operator binds the regular expression to a variable or data stream.
It is important to note that there are different regular expression syntaxes. Some editors and command-line tools (for example, grep) allow the user to select which regular expression syntax they prefer to use. PERL-Compatible Regular Expressions (PCRE) are by far the most powerful.
Regular expressions used in matching operations
The result of applying the regular expression to a variable or data stream is usually a value that, when used in a flow-control statement such as if or while, will evaluate to true or false depending on whether or not the match succeeded. There are modifiers that can be appended to the closing slash of a regular expression to change its return value.
Line 45 of the Tic-Tac-Toe program provides a typical example of how a regular expression is used in a PERL program. The regular expression [1-9] is being applied to the variable game which holds the in-memory representation of the Tic-Tac-Toe game board. The expression is a character class that matches any character in the range from 1 to 9 (inclusive). The result of the regular expression will be true only if a character from 1 to 9 is present in what is being evaluated. On line 45, the !~ operator applies the regular expression to the game variable and negates its sense such that the result will be true only if none of the characters from 1 to 9 are present. Because the regular expression is embedded within the conditional clause of the ifstatement modifier, the statement last PROMPT is only executed if there are no characters in the range from 1 to 9 left on the game board.
The last statement is one of a few flow-control statements in PERL that allow the program execution sequence to jump from the current line to another line somewhere else in the program. Other flow-control statements that work in a similar fashion include next, continue, redo and goto (the goto statement should be avoided whenever possible because it allows for spaghetti code).
In the example Tic-Tac-Toe program, the last PROMPT statement on line 45 causes program execution to resume just after the PROMPT block. Because there are no more statements in the program, the program will terminate.
The label PROMPT was chosen arbitrarily. Any label (or none at all) could have been used.
The redo PROMPT statement at the end of the PROMPT block causes program execution to jump back to the beginning of the PROMPT block.
Notice that the state keyword like the my keyword creates a variable that can only be accessed or modified within the block that it is created (or a nested sub-block if any exist). Unlike the my keyword, variables created with the state keyword keep their former value when the blocks they are in are called repeatedly. This is the behavior that is needed for the game variable because it is being updated incrementally each time the PROMPT block is run. The mark and move variables are meant to be different on each iteration of the PROMPT block, so they do not need to be created with the state keyword.
Regular expressions used for input validation
Another common use of regular expressions is for input validation. Line 34 of the example Tic-Tac-Toe program provides an example of a regular expression being used for input validation. The expression on line 34 is similar to the one on line 45. It is also checking for characters from 1 to 9. However, it is performing the check against the null filehandle (<>); it is using the =~ operator; and it is prefixed and suffixed with the zero-width assertions^ and $ respectively.
The null filehandle, when accessed as it is on line 34, will cause the program to pause until one line of input is provided. The regular expression will evaluate to true only if the line contains one character in the range from 1 to 9. The assertions ^ and $ do not match any characters. Rather, they match the beginning and end positions, respectively, on the line. The regular expression effectively reads: “Begin (^) with one character in the range from 1 to 9 ([1-9]) and end ($)”.
Because it is embedded in the conditional clause of the ternary operator, line 34 will return either what was matched ($&) if the match succeeded or the character zero (0) if it failed. If the input were not validated in this way, then the user could submit their opponent’s mark rather than a number on the board.
Regular expressions used for filtering data
Line 17 demonstrates using the global modifier (g) on a regular expression. With the global modifier, the regular expression will return the number of matches instead of true or false. In list context, it returns a list of all the matched substrings.
Line 17 uses a regular expression to copy all the numbers in the range from 1 to 9 from the game variable into the array named nums. Line 18 then uses the modulo operator with the integer 2 as its second argument to determine whether the length of the nums array is even or odd. The formula on line 18 will result in 0 if the length of nums is odd and 1 if the length of nums is even. Finally, the computed index (indx) is used to access an element of the MARKS array and return it. Using this formula, the get_mark function will alternately return X or O depending on whether there are an odd or even number of positions left on the board.
Regular expressions used for substituting data
Line 28 demonstrates yet another common use of regular expressions in PERL. Rather than being used in a match operator (m), the regular expression on line 28 is being used in a substitution operator (s). If the value in the move variable is found in the game variable, it will be substituted with the value of the mark variable.
PERL sigils and data types
The last things of note that are used in the example Tic-Tac-Toe program are the sigils ($ and @) that are placed before the variable names. When creating a variable, the sigil indicates the type of variable being created. It is important to note that a different sigil can be prefixed to the variable name when it is accessed to indicate whether one or many items should be returned from the variable.
There are three built-in data types in PERL: scalars ($), arrays (@) and associative arrays (%). Scalars hold a single data item such as a number, character or string of characters. Arrays are numerically indexed sets of scalars. Associative arrays are arrays that are indexed by scalars rather than numbers.
Kunai Team Discusses The “Very Stressful” Impacts Of Metacritic Review-Bombing
‘Review-bombing’ seems to be becoming more and more popular these days, with Kunai becoming the latest game to receive such treatment from a disgruntled stranger. If you’re unaware, the term refers to the act of giving games a very low and unjustified user score on websites such as Metacritic, lowering its overall user review score average and therefore indicating that it’s a ‘bad’ game.
We’ve almost come to expect it with certain major releases – both major Pokémon releases have been targetted on Switch, with fans being quick to accuse developer Game Freak of every trick under the sun, and games like Astral Chain have also come under fire simply for being exclusive to the console – but the trend appears to be moving towards indie games, too.
Game programmer Benjamin de Jager managed to find out that, in Kunai’s case, there was only one person to blame which is extra-unusual. In a blog post on Gamasutra, he presented evidence of a Reddit user almost boasting about their revew-bombing antics, explaining that they manipulated Metacritic’s score system. The bomber said, “I made like 200 different accounts just to ruin the game’s score”.
This image was shared on February 19th, showing the game with a 1.7 user score on Metacritic
Some of the negative impacts of an act like this are obvious – would you spend money on a game if you saw that lots of (seemingly real) users appeared to overwhelmingly dislike it? – but it goes much deeper than that. The folks over at GamesIndustry.biz have shared an interview with producer Bram Stege and Dotemu head of marketing Arnaud De Sousa, who explain the “very stressful” impacts review-bombing can have. We’ve shared some select quotes below.
De Sousa: “Review bombings are something we see from time to time. But usually not on indie games, and usually they have a message behind it. Because developers change something, because the online is really bad — usually there’s an agenda behind it. But here it’s just a random dude picking a random game to review bomb because they can.”
Stege: “It causes stress. You hope that the audience of Metacritic is smart enough to see, ‘Oh, they got an 8.3 from the critics and a 1.6 from players, so there must be something up.’ You hope it doesn’t affect sales. I don’t know if it affected sales. But it does generate a lot of stress. You’ve been working for two years on this game. You put all the blood, sweat, and tears into it. And then one guy on a Sunday afternoon with basically no effort can bomb your score from a big, positive score to a 1.7. It’s very stressful.”
It also has an effect on a studio going forward, especially when it comes to learning about what players like and dislike about certain game features.
De Sousa: “We’re always looking at reviews. It’s interesting just to have the feedback… When you’re working on the game for two years, you get tunnel vision and you don’t always see other points of view. Sometimes, we see reviews and it’s just someone who played the game 20 minutes and gave it a 0, so it does depend on the quality of the reviews. But someone who played the game for 30 hours and gave good feedback, whether it’s positive or negative, it’s really interesting to read.”
The full interview is an interesting read, so we’d encourage you to check it out here if you’re interested.
The Office's John Krasinski Has A Marvel Hero He'd Love To Portray
John Krasinski, who despite all of his career advancements will always be Jim from The Office to us, has never been in a Marvel movie. Although he auditioned for Captain America (a role that went to Chris Evans), Krasinski now has his eyes on a different Marvel hero--Mr Fantastic, the leader of the Fantastic Four.
Talking to Total Film magazine (via Gamesradar) ahead of the release of A Quiet Place Part 2, which Krasinski directed, the actor talked about wanting to take on the role of Mr Fantastic. The Fantastic Four can now be incorporated into the Marvel Cinematic Universe following Disney's purchase of Fox.
"I would love to be in the Marvel universe," he said. "I love those movies because they’re fun, but I also think they’re really well done...I have no idea what [Marvel] are thinking. But if they are considering me for Mr. Fantastic, continue to consider me because I would love it."
Goal: Given a string that is either Morse code or normal text. Write a function that transforms the string into the other language: Morse code should be translated to normal text. Normal text should be translated to Morse code.
Output Example: Create a function morse(txt) that takes an input string argument txt and returns its translation:
Note that Morse code doesn’t differentiate lowercase or uppercase characters. So you just use uppercase characters as default translation output.
AlgorithmIdea: A simple algorithm is enough to solve the problem:
Detect if a string is Morse code or normal text. The simple but not perfect solution is to check if the first character is either the dot symbol '.' or the minus symbol '-'. Note that you can easily extend this by checking if all characters are either the dot symbol or the minus symbol (a simple regular expression will be enough).
Prepare a dictionary that maps all “normal text” symbols to their respective Morse code translations. Use the inverse dictionary (or create it ad-hoc) to get the inverse mapping.
Iterate over all characters in the string and use the dictionary to translate each character separately.
Implementation: Here’s the Python implementation of the above algorithm for Morse code translation:
def morse(txt): '''Morse code encryption and decryption''' d = {'A':'.-','B':'-...','C':'-.-.','D':'-..','E':'.', 'F':'..-.','G':'--.','H':'....','I':'..','J':'.---', 'K':'-.-','L':'.-..','M':'--','N':'-.','O':'---', 'P':'.--.','Q':'--.-','R':'.-.','S':'...','T':'-', 'U':'..-','V':'...-','W':'.--','X':'-..-','Y':'-.--', 'Z':'--..', ' ':'.....'} translation = '' # Encrypt Morsecode if txt.startswith('.') or txt.startswith('−'): # Swap key/values in d: d_encrypt = dict([(v, k) for k, v in d.items()]) # Morse code is separated by empty space chars txt = txt.split(' ') for x in txt: translation += d_encrypt.get(x) # Decrypt to Morsecode: else: txt = txt.upper() for x in txt: translation += d.get(x) + ' ' return translation.strip() print(morse('python'))
# .--. -.-- - .... --- -.
print(morse('.--. -.-- - .... --- -.'))
# PYTHON
print(morse(morse('HEY')))
# HEY
Algorithmic complexity: The runtime complexity is linear in the length of the input string to be translated—one translation operation per character. Dictionary membership has constant runtime complexity. The memory overhead is also linear in the input text as all the characters have to be hold in memory.
AlternativeImplementation: Albrecht also proposed a much shorter alternative:
def morse(txt): encrypt = {'A':'.-', 'B':'-...', 'C':'-.-.', 'D':'-..', 'E':'.', 'F':'..-.', 'G':'--.', 'H':'....', 'I':'..', 'J':'.---', 'K':'-.-', 'L':'.-..', 'M':'--', 'N':'-.', 'O':'---', 'P':'.--.', 'Q':'--.-', 'R':'.-.', 'S':'...', 'T':'-', 'U':'..-', 'V':'...-', 'W':'.--', 'X':'-..-', 'Y':'-.--', 'Z':'--..', ' ':'.....'} decrypt = {v: k for k, v in encrypt.items()} if '-' in txt: return ''.join(decrypt[i] for i in txt.split()) return ' '.join(encrypt[i] for i in txt.upper()) print(morse('python'))
# .--. -.-- - .... --- -.
print(morse('.--. -.-- - .... --- -.'))
# PYTHON
print(morse(morse('HEY')))
# HEY
It uses dict comprehension and generator expressions to make it much more concise.