One significant limitation of the netboot server built in this series is the operating system image being served is read-only. Some use cases may require the end user to modify the image. For example, an instructor may want to have the students install and configure software packages like MariaDB and Node.js as part of their course walk-through.
An added benefit of writable netboot images is the end user’s “personalized” operating system can follow them to different workstations they may use at later times.
Change the Bootmenu Application to use HTTPS
Create a self-signed certificate for the bootmenu application:
Verify your certificate’s values. Make sure the “CN” value in the “Subject” line matches the DNS name that your iPXE clients use to connect to your bootmenu server:
Update init.ipxe to use HTTPS. Then recompile the ipxe bootloader with options to embed and trust the self-signed certificate you created for the bootmenu application:
$ echo '#define DOWNLOAD_PROTO_HTTPS' >> $HOME/ipxe/src/config/local/general.h
$ sed -i 's/^chain http:/chain https:/' $HOME/ipxe/init.ipxe
$ cp $MY_TLSD/$MY_NAME.pem $HOME/ipxe
$ cd $HOME/ipxe/src
$ make clean
$ make bin-x86_64-efi/ipxe.efi EMBED=../init.ipxe CERT="../$MY_NAME.pem" TRUST="../$MY_NAME.pem"
You can now copy the HTTPS-enabled iPXE bootloader out to your clients and test that everything is working correctly:
Add a library to the bootmenu application that uses the Authen-PAM perl module to perform user authentication:
# dnf install -y perl-Authen-PAM;
# MY_MOJO=/opt/bootmenu
# mkdir $MY_MOJO/lib
# cat << 'END' > $MY_MOJO/lib/PAM.pm
package PAM; use Authen::PAM; sub auth { my $success = 0; my $username = shift; my $password = shift; my $callback = sub { my @res; while (@_) { my $code = shift; my $msg = shift; my $ans = ""; $ans = $username if ($code == PAM_PROMPT_ECHO_ON()); $ans = $password if ($code == PAM_PROMPT_ECHO_OFF()); push @res, (PAM_SUCCESS(), $ans); } push @res, PAM_SUCCESS(); return @res; }; my $pamh = new Authen::PAM('bootmenu', $username, $callback); { last unless ref $pamh; last unless $pamh->pam_authenticate() == PAM_SUCCESS; $success = 1; } return $success;
} return 1;
END
The above code is taken almost verbatim from the Authen::PAM::FAQ man page.
Redefine the bootmenu application so it returns a netboot template only if a valid username and password are supplied:
# cat << 'END' > $MY_MOJO/bootmenu.pl
#!/usr/bin/env perl use lib 'lib'; use PAM;
use Mojolicious::Lite;
use Mojolicious::Plugins;
use Mojo::Util ('url_unescape'); plugin 'Config'; get '/menu';
get '/boot' => sub { my $c = shift; my $instance = $c->param('instance'); my $username = $c->param('username'); my $password = $c->param('password'); my $template = 'menu'; { last unless $instance =~ /^fc[[:digit:]]{2}$/; last unless $username =~ /^[[:alnum:]]+$/; last unless PAM::auth($username, url_unescape($password)); $template = $instance; } return $c->render(template => $template);
}; app->start;
END
The bootmenu application now looks for the lib directory relative to its WorkingDirectory. However, by default the working directory is set to the root directory of the server for systemd units. Therefore, you must update the systemd unit to set WorkingDirectory to the root of the bootmenu application instead:
# sed -i "/^RuntimeDirectory=/ a WorkingDirectory=$MY_MOJO" /etc/systemd/system/bootmenu.service
# systemctl daemon-reload
Update the templates to work with the redefined bootmenu application:
# cd $MY_MOJO/templates
# MY_BOOTMENU_SERVER=$(</etc/hostname)
# MY_FEDORA_RELEASES="28 29"
# for i in $MY_FEDORA_RELEASES; do echo '#!ipxe' > fc$i.html.ep; grep "^kernel\|initrd" menu.html.ep | grep "fc$i" >> fc$i.html.ep; echo "boot || chain https://$MY_BOOTMENU_SERVER/menu" >> fc$i.html.ep; sed -i "/^:f$i$/,/^boot /c :f$i\nlogin\nchain https://$MY_BOOTMENU_SERVER/boot?instance=fc$i\&username=\${username}\&password=\${password:uristring} || goto failed" menu.html.ep; done
The result of the last command above should be three files similar to the following:
Now, restart the bootmenu application and verify authentication is working:
# systemctl restart bootmenu.service
Make the iSCSI Target Writeable
Now that user authentication works through iPXE, you can create per-user, writeable overlays on top of the read-only image on demand when users connect. Using a copy-on-write overlay has three advantages over simply copying the original image file for each user:
The copy can be created very quickly. This allows creation on-demand.
The copy does not increase the disk usage on the server. Only what the user writes to their personal copy of the image is stored in addition to the original image.
Since most sectors for each copy are the same sectors on the server’s storage, they’ll likely already be loaded in RAM when subsequent users access their copies of the operating system. This improves the server’s performance because RAM is faster than disk I/O.
One potential pitfall of using copy-on-write is that once overlays are created, the images on which they are overlayed must not be changed. If they are changed, all the overlays will be corrupted. Then the overlays must be deleted and replaced with new, blank overlays. Even simply mounting the image file in read-write mode can cause sufficient filesystem updates to corrupt the overlays.
Due to the potential for the overlays to be corrupted if the original image is modified, mark the original image as immutable by running:
# chattr +i </path/to/file>
You can use lsattr </path/to/file> to view the status of the immutable flag and use to chattr -i </path/to/file> unset the immutable flag. While the immutable flag is set, even the root user or a system process running as root cannot modify or delete the file.
Begin by stopping the tgtd.service so you can change the image files:
# systemctl stop tgtd.service
It’s normal for this command to take a minute or so to stop when there are connections still open.
Now, remove the read-only iSCSI export. Then update the readonly-root configuration file in the template so the image is no longer read-only:
# MY_FC=fc29
# rm -f /etc/tgt/conf.d/$MY_FC.conf
# TEMP_MNT=$(mktemp -d)
# mount /$MY_FC.img $TEMP_MNT
# sed -i 's/^READONLY=yes$/READONLY=no/' $TEMP_MNT/etc/sysconfig/readonly-root
# sed -i 's/^Storage=volatile$/#Storage=auto/' $TEMP_MNT/etc/systemd/journald.conf
# umount $TEMP_MNT
Journald was changed from logging to volatile memory back to its default (log to disk if /var/log/journal exists) because a user reported his clients would freeze with an out-of-memory error due to an application generating excessive system logs. The downside to setting logging to disk is that extra write traffic is generated by the clients, and might burden your netboot server with unnecessary I/O. You should decide which option — log to memory or log to disk — is preferable depending on your environment.
Since you won’t make any further changes to the template image, set the immutable flag on it and restart the tgtd.service:
# cat << 'END' > $MY_MOJO/bootmenu.pl
#!/usr/bin/env perl use lib 'lib'; use PAM;
use Mojolicious::Lite;
use Mojolicious::Plugins;
use Mojo::Util ('url_unescape'); plugin 'Config'; get '/menu';
get '/boot' => sub { my $c = shift; my $instance = $c->param('instance'); my $username = $c->param('username'); my $password = $c->param('password'); my $chapscrt; my $template = 'menu'; { last unless $instance =~ /^fc[[:digit:]]{2}$/; last unless $username =~ /^[[:alnum:]]+$/; last unless PAM::auth($username, url_unescape($password)); last unless $chapscrt = `sudo scripts/mktgt $instance $username`; $template = $instance; } return $c->render(template => $template, username => $username, chapscrt => $chapscrt);
}; app->start;
END
This new version of the bootmenu application calls a custom mktgt script which, on success, returns a random CHAP password for each new iSCSI target that it creates. The CHAP password prevents one user from mounting another user’s iSCSI target by indirect means. The app only returns the correct iSCSI target password to a user who has successfully authenticated.
The mktgt script is prefixed with sudo because it needs root privileges to create the target.
The $username and $chapscrt variables also pass to the render command so they can be incorporated into the templates returned to the user when necessary.
Next, update our boot templates so they can read the username and chapscrt variables and pass them along to the end user. Also update the templates to mount the root filesystem in rw (read-write) mode:
# cd $MY_MOJO/templates
# sed -i "s/:$MY_FC/:$MY_FC-<%= \$username %>/g" $MY_FC.html.ep
# sed -i "s/ netroot=iscsi:/ netroot=iscsi:<%= \$username %>:<%= \$chapscrt %>@/" $MY_FC.html.ep
# sed -i "s/ ro / rw /" $MY_FC.html.ep
After running the above commands, you should have boot templates like the following:
NOTE: If you need to view the boot template after the variables have been interpolated, you can insert the “shell” command on its own line just before the “boot” command. Then, when you netboot your client, iPXE gives you an interactive shell where you can enter “imgstat” to view the parameters being passed to the kernel. If everything looks correct, you can type “exit” to leave the shell and continue the boot process.
Now allow the bootmenu user to run the mktgt script (and only that script) as root via sudo:
# echo "bootmenu ALL = NOPASSWD: $MY_MOJO/scripts/mktgt *" > /etc/sudoers.d/bootmenu
The bootmenu user should not have write access to the mktgt script or any other files under its home directory. All the files under /opt/bootmenu should be owned by root, and should not be writable by any user other than root.
Sudo does not work well with systemd’s DynamicUser option, so create a normal user account and set the systemd service to run as that user:
Finally, create a directory for the copy-on-write overlays and create the mktgt script that manages the iSCSI targets and their overlayed backing stores:
# mkdir /$MY_FC.cow
# mkdir $MY_MOJO/scripts
# cat << 'END' > $MY_MOJO/scripts/mktgt
#!/usr/bin/env perl # if another instance of this script is running, wait for it to finish "$ENV{FLOCKER}" eq 'MKTGT' or exec "env FLOCKER=MKTGT flock /tmp $0 @ARGV"; # use "RETURN" to print to STDOUT; everything else goes to STDERR by default
open(RETURN, '>&', STDOUT);
open(STDOUT, '>&', STDERR); my $instance = shift or die "instance not provided";
my $username = shift or die "username not provided"; my $img = "/$instance.img";
my $dir = "/$instance.cow";
my $top = "$dir/$username"; -f "$img" or die "'$img' is not a file"; -d "$dir" or die "'$dir' is not a directory"; my $base;
die unless $base = `losetup --show --read-only --nooverlap --find $img`;
chomp $base; my $size;
die unless $size = `blockdev --getsz $base`;
chomp $size; # create the per-user sparse file if it does not exist
if (! -e "$top") { die unless system("dd if=/dev/zero of=$top status=none bs=512 count=0 seek=$size") == 0;
} # create the copy-on-write overlay if it does not exist
my $cow="$instance-$username";
my $dev="/dev/mapper/$cow";
if (! -e "$dev") { my $over; die unless $over = `losetup --show --nooverlap --find $top`; chomp $over; die unless system("echo 0 $size snapshot $base $over p 8 | dmsetup create $cow") == 0;
} my $tgtadm = '/usr/sbin/tgtadm --lld iscsi'; # get textual representations of the iscsi targets
my $text = `$tgtadm --op show --mode target`;
my @targets = $text =~ /(?:^T.*\n)(?:^ .*\n)*/mg; # convert the textual representations into a hash table
my $targets = {};
foreach (@targets) { my $tgt; my $sid; foreach (split /\n/) { /^Target (\d+)(?{ $tgt = $targets->{$^N} = [] })/; /I_T nexus: (\d+)(?{ $sid = $^N })/; /Connection: (\d+)(?{ push @{$tgt}, [ $sid, $^N ] })/; }
} my $hostname;
die unless $hostname = `hostname`;
chomp $hostname; my $target = 'iqn.' . join('.', reverse split('\.', $hostname)) . ":$cow"; # find the target id corresponding to the provided target name and
# close any existing connections to it
my $tid = 0;
foreach (@targets) { next unless /^Target (\d+)(?{ $tid = $^N }): $target$/m; foreach (@{$targets->{$tid}}) { die unless system("$tgtadm --op delete --mode conn --tid $tid --sid $_->[0] --cid $_->[1]") == 0; }
} # create a new target if an existing one was not found
if ($tid == 0) { # find an available target id my @ids = (0, sort keys %{$targets}); $tid = 1; while ($ids[$tid]==$tid) { $tid++ } # create the target die unless -e "$dev"; die unless system("$tgtadm --op new --mode target --tid $tid --targetname $target") == 0; die unless system("$tgtadm --op new --mode logicalunit --tid $tid --lun 1 --backing-store $dev") == 0; die unless system("$tgtadm --op bind --mode target --tid $tid --initiator-address ALL") == 0;
} # (re)set the provided target's chap password
my $password = join('', map(chr(int(rand(26))+65), 1..8));
my $accounts = `$tgtadm --op show --mode account`;
if ($accounts =~ / $username$/m) { die unless system("$tgtadm --op delete --mode account --user $username") == 0;
}
die unless system("$tgtadm --op new --mode account --user $username --password $password") == 0;
die unless system("$tgtadm --op bind --mode account --tid $tid --user $username") == 0; # return the new password to the iscsi target on stdout
print RETURN $password;
END
# chmod +x $MY_MOJO/scripts/mktgt
The above script does five things:
It creates the /<instance>.cow/<username> sparse file if it does not already exist.
It creates the /dev/mapper/<instance>-<username> device node that serves as the copy-on-write backing store for the iSCSI target if it does not already exist.
It creates the iqn.<reverse-hostname>:<instance>-<username> iSCSI target if it does not exist. Or, if the target does exist, it closes any existing connections to it because the image can only be opened in read-write mode from one place at a time.
It (re)sets the chap password on the iqn.<reverse-hostname>:<instance>-<username> iSCSI target to a new random value.
It prints the new chap password on standard output if all of the previous tasks compeleted successfully.
You should be able to test the mktgt script from the command line by running it with valid test parameters. For example:
# echo `$MY_MOJO/scripts/mktgt fc29 jsmith`
When run from the command line, the mktgt script should print out either the eight-character random password for the iSCSI target if it succeeded or the line number on which something went wrong if it failed.
On occasion, you may want to delete an iSCSI target without having to stop the entire service. For example, a user might inadvertently corrupt their personal image, in which case you would need to systematically undo everything that the above mktgt script does so that the next time they log in they will get a copy of the original image.
Below is an rmtgt script that undoes, in reverse order, what the above mktgt script did:
# mkdir $HOME/bin
# cat << 'END' > $HOME/bin/rmtgt
#!/usr/bin/env perl @ARGV >= 2 or die "usage: $0 <instance> <username> [+d|+f]\n"; my $instance = shift;
my $username = shift; my $rmd = ($ARGV[0] eq '+d'); #remove device node if +d flag is set
my $rmf = ($ARGV[0] eq '+f'); #remove sparse file if +f flag is set
my $cow = "$instance-$username"; my $hostname;
die unless $hostname = `hostname`;
chomp $hostname; my $tgtadm = '/usr/sbin/tgtadm';
my $target = 'iqn.' . join('.', reverse split('\.', $hostname)) . ":$cow"; my $text = `$tgtadm --op show --mode target`;
my @targets = $text =~ /(?:^T.*\n)(?:^ .*\n)*/mg; my $targets = {};
foreach (@targets) { my $tgt; my $sid; foreach (split /\n/) { /^Target (\d+)(?{ $tgt = $targets->{$^N} = [] })/; /I_T nexus: (\d+)(?{ $sid = $^N })/; /Connection: (\d+)(?{ push @{$tgt}, [ $sid, $^N ] })/; }
} my $tid = 0;
foreach (@targets) { next unless /^Target (\d+)(?{ $tid = $^N }): $target$/m; foreach (@{$targets->{$tid}}) { die unless system("$tgtadm --op delete --mode conn --tid $tid --sid $_->[0] --cid $_->[1]") == 0; } die unless system("$tgtadm --op delete --mode target --tid $tid") == 0; print "target $tid deleted\n"; sleep 1;
} my $dev = "/dev/mapper/$cow";
if ($rmd or ($rmf and -e $dev)) { die unless system("dmsetup remove $cow") == 0; print "device node $dev deleted\n";
} if ($rmf) { my $sf = "/$instance.cow/$username"; die "sparse file $sf not found" unless -e "$sf"; die unless system("rm -f $sf") == 0; die unless not -e "$sf"; print "sparse file $sf deleted\n";
}
END
# chmod +x $HOME/bin/rmtgt
For example, to use the above script to completely remove the fc29-jsmith target including its backing store device node and its sparse file, run the following:
# rmtgt fc29 jsmith +f
Once you’ve verified that the mktgt script is working properly, you can restart the bootmenu service. The next time someone netboots, they should receive a personal copy of the the netboot image they can write to:
# systemctl restart bootmenu.service
Users should now be able to modify the root filesystem as demonstrated in the below screenshot:
Samsung has a long history of mocking Apple before copying it
Stop us if you’ve heard this one. Apple makes some change to its iPhones, Samsung’s PR company mocks the very idea —and finally Samsung copies it. Sometimes the company keeps a low profile, sometimes it shouts about Apple’s missteps, but always, always Samsung then goes the same way.
Samsung logo with an Apple-style bite taken out of it
We’re not going to critcize Samsung phones here. Let’s not even get into the argument that Android copied iOS —partly because yes, of course it did, but mostly because we want to specifically examine Samsung.
The company usually makes a case that its technology is ahead of Apple’s and while you can regularly dispute that, it is often quite true. Samsung’s phones were waterproof before the iPhone was, for instance, and later in 2019 it’s highly likely that they will release 5G-capable phones and Apple won’t.
What we can’t get over is how Samsung’s PR department keeps hammering on this same nail. As part of all this, it regularly lampoons people who buy iPhones as being deaf to Samsung’s alleged technology superiority —but it treats its own users as being blind. Where Apple users sometimes get called sheep, Samsung is always hoping that its own users have goldfish memories.
The latest case is of course to do with the notch in the iPhone X range which naturally features far more prominently in Samsung’s advertising than it does in Apple’s own.
Yet this all goes back a long way. If it’s usually in such a specific sequence that you could predict when Samsung will mock and how many months later it will copy, there are occasions when its PR company is just wilfully ignoring the facts in order to take a shot at Apple.
Such as with Apple Stores. This one took a long time as Apple Stores opened in 2001 and it was late 2018 when Samsung ran a series of ads spoofing them.
That was part of Samsung’s series of ads called Ingenius which are all set in a mockup of Apple Stores and use, well, mockups of Apple Genius staff.
To be fair, Samsung could’ve done much the same thing with Microsoft Stores and would there have saved some money by not having to hire so many extras as customers.
Yet they could also have used their own stores. There are Samsung Experience Stores and there have been since they were introduced in 2013. It’s easier to find the website for them than it is an actual store, though. And that’s in part because of the last line on the page. “Finding a Samsung Store inside Best Buy near you is easy. Just enter your zip code.”
We added the emphasis but we didn’t enter our zip code—because there’s nowhere to type it. We do hope that this is a fluke, some temporary hiccup, because each time we try, we see only this the page.
Surely this usually works
It’s a gorgeously-designed page in the sense of how it looks but it doesn’t actually work.
Lightning fast
So Samsung is mocking the Apple Store experience when you didn’t even know that there was a Samsung Experience Store. Shortly before it opened these shelves inside Best Buy, Samsung also ripped Apple apart for how the company changed from a 30-pin dock to a Lightning cable.
This was 2012 and when we’re reminded that Apple made this change at all, it is startling to realise it was so long ago now. Samsung was right that it was happening and Samsung had a point about how big a change it was. To this day, you will find 30-pin connectors on devices in hotels, for instance.
What was that about changing from 30-pin to Lightning?
That’s apparently the fistful of different cables that you needed to charge all the variations of Samsung phones. In 2012, it was being sold as a 17-in-1 set and today it’s an 18-in-1 set so either the makers missed one or Samsung’s done it again —without Apple mocking them.
Blatant
Call us idealistic, but we do credit customers with noticing things like this. We’re idealistic but also practical, though, so we wouldn’t assume that absolutely everybody would recognize a copy six years after the original. We do expect industry people too, however.
This one is Apple’s version in 2007. Call it Before.
And in 2013, Samsung’s After.
Innovation
In that case, Samsung used Apple’s advertising skill. In the cause of speed and efficiency, it skipped the bit where it first mocked Apple, it just went straight to using the ideas. This isn’t the only time it’s done that —see if you can spot any Apple-esque elements in this ad —but from around 2013, it kept quiet. For a while.
It’s as if it believes both industry experts and its own customers are so siloed that they won’t recognize a copy. They might well have a point there as usually Android advertising passes us by but we did pick up on Samsung’s great online payment innovation.
And Samsung couldn’t stop itself. While its advertising claimed that Samsung Pay was more widely accepted than any other system at all, it only showed an Apple Pay transaction failing. That claim about wide acceptance is qualified, by the way, with a little footnote saying “Refers to service coverage”.
We’re sure they’re right and the fact that it initially only worked with then then new Galaxy S6 Edge+ and Note 5 is just a detail. And actually, Samsung Pay does have an advantage over its rivals in that can work with old-style payment machines where you had to swipe your card.
Maybe that gag about failed Apple Pay transaction emboldened Samsung’s PR department, because it’s since then that they’ve gone all out to ridicule their Cupertino rival.
You don’t know jack
Civilization ended in 2016. That was when Apple dropped the headphone jack with the introduction of the iPhone 7. It was such a cataclysmic event that it may have taken you until 2018 to get over it —only to have another of Samsung’s Ingenius ads revive the trauma.
Take a guess what’s happening now. It appears that Samsung’s Galaxy A8S hasn’t got a headphone jack either. We’ll see what happens with the S10.
One notch
Someone at Samsung’s PR department is clearly spotting genuine issues with Apple’s iPhones, or at least things that could be genuine issues to some people. That dropping of the headphone jack was mildly inconvenient and it did mean we all have headphones lying around that we can’t use any more. It was definitely a valid point.
We’re just amused that nobody in Samsung’s PR department talked to Samsung itself. Fortunately, though, they would never make that mistake twice.
Italy’s anti-trust body fined Apple the equivalent of $11.4 million and Samsung only $5.7 million so maybe Samsung could claim a little higher moral ground. Except it didn’t, it carried right on mocking how Apple iPhones slow down.
That’s enough now
Then riddled throughout the whole series of Ingenious ads, there are also decreasingly subtle digs at Apple and at Apple fans for that notch introduced in the iPhone X.
There’s no disputing that it detracts from the otherwise edge to edge display on the iPhone X, XS, XS Max and XR. You might not mind it, but you know that it would be nicer if it weren’t there. That said, you also know that it’s necessary. The notch is where Apple puts its TrueDepth technology which powers the Face ID system.
Samsung can’t let Apple be the only one with working Face ID so its new phones are set to have the same idea, at least to an extent. And in the case of the Samsung A8S, that same idea is going to feature what looks like a hole punch in the display.
It’s not a notch, you’ve got to give them that
It’s up to you, it’s up to each of us, whether we find that more distracting than a notch but the same thing applies. The display would be better without it.
And there’s one other thing that you know applies. Apple is not going to mock Samsung’s hole punch in its advertising.
Classy
We’re going to say that, yes, Apple is too classy to hammer on Samsung in its major advertising campaigns. However, it’s also smarter. Possibly it’s also more arrogant, but it’s definitely smarter.
All phone manufacturers copy from —are inspired by —each other and, again, Samsung has legitimately beaten Apple to certain features.
Yet, the way that Samsung keeps on going through same loop of derision and copying leaves us feeling that it’s an also-ran. That’s wrong, Samsung makes some great phones yet this pummelling away at Apple is dangerous.
And having your ad agency insult the buyers of your rival’s products doesn’t feel like a winner, either. Maybe it is, maybe this is why Samsung is doing so well compared to all other Android makers.
Posted by: xSicKxBot - 01-14-2019, 11:10 AM - Forum: Lounge
- No Replies
These were the most downloaded games on the PlayStation Store in 2018
FIFA 19, Call of Duty: Black Ops 4, and Red Dead Redemption 2 were the most downloaded titles on the PlayStation Store throughout 2018.
The news comes straight from Sony, with the company naming the top 20 most downloaded PlayStation 4 and PlayStation VR titles in a post on the PlayStation Blog.
Familiar names like Beat Saber, Job Simulator, and Superhot VR topped the PlayStation VR download charts, and were joined in the top 10 by the likes of Skyrim VR and Moss.
Although the console maker didn’t reveal any exact download figures, it’s still interesting to see which games thrived on its digital marketplace last year.
We’ve spotlighted the 10 most downloaded PS4 and PSVR games below, but those interested can check out the full lists by clicking right here.
Posted by: xSicKxBot - 01-14-2019, 11:10 AM - Forum: Lounge
- No Replies
Blog: Applying level flow in games like Uncharted 4 and The Last of Us
The following blog post, unless otherwise noted, was written by a member of Gamasutras community. The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
For the past few months I have been researching several different games. During that time I have been researching games like “Uncharted 4” and “The Last of Us” (made by Naughty Dog).
With this article I want to share my knowledge with my fellow peers, in the hope of empowering and motivating them to learn more about level design. This will be a crash course on the different elements of level flow, that level designers can use to make informed decisions about their level design.
1 – Introduction: What is level flow
My definition of level flow:
“When the player knows what to do, where to go.
But not always know how to achieve/get towards that goal.”
(keyword: Spatial Awareness)
It is a state where the player has a pleasant experience, traversing through the level. It goes hand in hand with game flow.
This definition is quite vague and that is because level flow is a broad subject. For simplicity I will split up “level flow” into four (4) smaller pieces. In high-level terms, these are some of the elements we level designers use to guide the player(s)..
“I need to know about geometry and composition? But I am not an artist?!”
Yes, I am also not an artist but I do believe that everything is in some way intertwined with level design. Mastering small bits about these subjects will allow you to make more informed design decisions.
Geometry
Think about collision, physical interactive objects, shape design.
Composition
A) Focal points. Funneling the player with use of Geometry/Assets.
B) Contrast (positive & negative space): Between, Space, Lighting or Color.
Other events that makes the player move: such as an explosion or a fallen tree trunk.
Storytelling
Text/Signs (direct)
Assets placed in a particular order, like pickups scattered across the map or barrels in a corner (indirect)
Geometry, Composition and Scripted Events can be combined to create Storytelling elements. Being able to master these sections will allow you to guide/move the player to where ever you desire them to go.
Here are some examples of flow elements that can be used to guide the player through the level.
2.1 – Examples: The use of lines
Lines, Arrows Shape Silhouettes, Pathways…
Lines have two points, a begin and an endpoint. A line affords direction. It is a 2D object that moves in a direction. We can see lines as arrows and arrows afford direction.
In this example, multiple objects in the scene will hint towards this focal point, the mega structure.
Nathan Drake points at the landmark. (not in this picture, but in game he does)
The pathway underneath them, leads towards the landmark.
The shape of the mountains.
The shape of the houses (especially the roofs)
The contrast between the mountains and the forest.
As you can see lines are powerful tools to indicate direction. They help to guide the players eye from A to B and visa versa.
2.2 – Examples: Landmark Visibility
Landmark definition:
An object or feature of a landscape or town that is easily seen and recognized from a distance, especially one that enables the player to establish their location on the map.
Landmarks can be used to determine someone’s location, approximately from the landmark. Therefore it is a method to improve flow in the level. An exceptional level designer would work together with the environment artists, to make sure that each area is recognizable. They should work together to determine the line of sight and the visual language of the area.
In this example, Joel will be able to see the bridge from multiple angles. This allows the level designer to create a level that doesn’t go into a linear/straight direction. As walking straight towards the objective is boring and no fun.
The high buildings on the side also helps to frame the bridge, funneling the player towards the objective. The only indication the player needs to know is how far away they are from the bridge. If they are approaching closer to the bridge, they can assume that they are going towards the right direction.
2.3 – Examples: The use of Color
Using Color as Affordance:
Color can be used to indicate the player, that a certain object is able to afford something. It can be used to contrast the scene, shifting the focal point.
In this example, all reachable & climbable ledges have these “light yellowish” color casted on them. Informing the player that those afford to be grabbed/climbed. This is a clever way to indicate something to the player, without it breaking the immersion. By blending in with the cliffs, using the same “earthly” tones.
You can also use color to invoke an emotion from the player.
Bright shades of red and yellow might indicate danger , while a blue color let them think about water, the sky, calmness or peace.
2.4 – Examples: Repetition, good or bad?
Repetition is beautiful as humans can see patterns. Nature is build up out of patterns and we love it.
But when you repeat it too often, it becomes boring. You can compare it to listening to the same song for 100x times. At first you might like the song, although after repeatedly listening to it, you might come to hate it.
This problem is also true in level/environment design. Do not let the player(s) traverse through areas that all look the same. What is the point of exploring if everything looks the same?
You can keep it look coherent, but be sure to have a bit of variation. As mentioned in the previous point: Color is a nice way to break up the monotone feel of a scene and to attract the players attention.
3.1 – Examples: Movement in a Static World
In a static scene, movement will catch the players eyes. When characters or objects move from one position to another position, they create a line. (See example 2.1) As I mentioned previously, a line indicates direction. We can use a dynamic element to guide the player through the level, creating flow.
Video by: Dops Gaming
Do you know the way?
In this example, Nathan breaks out of prison with two of his comrades. In this action packed scene, your goal is to escape the prison. The player can experience this scene as stressful and rushed. You aren’t prepared for this. You don’t even know the layout of the prison and now you have to make a break for it!
During this moment, the player doesn’t want to constantly think about where they need to go and accidently get lost. This is where the two side characters take it over and guide you through the scene.
3.2 – Examples: Movement, Following the Crowd
I don’t know where to go, guess I follow everyone else.
This is another example of movement being used. Similar to the previous example, the player is confronted with a high intensive experience. Where “yet again” the goal is to escape from the mess you’re in.
Video by: theRadBrad (fragment: 10:30 – 13:30)
In all the chaos you don’t know where to go, so you follow the crowd. Where ever they go, you will follow. Your only goal is to get out and keep Sarah safe.
The crowd is moved by “seemingly” uncontrollable events in the scene. An exploding car would drive the crowd to the opposite direction, towards safety.
It doesn’t have to be complicated. The previous two examples requires the developers to create AI with a behavior system. Although that could be really cool, it’s also complicated.
Video by: IFreeMz (fragment: 42:18 – 42:30)
A subtle tumble weed rolling in a certain direction or in this example; a swan flying away into the distance. It tells you to keep moving in “that” direction.
4.1 – Examples: Flow through Storytelling elements
The easiest noticeable storytelling elements are:
Text, signs
Decals
Meshes placed in a deliberate order
You can make patterns or create contrast to highlight an object.
Due to how the tank is angled 45 degrees, it naturally guides the player towards the left side. The tank is used as a physical barrier/obstacle to guide the player to the left.
Signs will tell you where to go. The left billboard reads: “Medical Evacuation, Use Tunnel” while the right billboard reads “Salt Lake City, Military Zone Ahead”. Given that the theme of the game is about survival, the player wants to avoid danger.
Another example is to use breadcrumbs to assist your player through the level. It can be a way to indicate the player that they are on the right path.
5.1 – Why everything I mentioned about composition is wrong (kind of…)
Well, 3D levels are created in…3D.
Cool 2D -> 3D street art from talented artist: Julian Beever
It is easier to make a 2D picture look nice from one view. But in games where the player can freely roam around and explore, they usually have multiple views on an object.
You and the environment artists can make everything look nice, but you probably don’t have all the time of the world to make it perfect.
However, as a level designer you can plan ahead and make sure to get the most out of the level, by setting up rules for yourself.
Limit the views the player can have.
Pay detail to the more important aspects. What do you want the player to see?
Try out different lighting setups.
Guide the player through the map with use of flow elements! Make the chances that the player wants to go off-track unlikely! Don’t place landmarks at spots where you don’t want the player to go to. Uncharted 4 levels feel very open. But secretly their levels are linear, with a golden path.
There is no point in going off road, there is nothing there anyway… oh look a cool mountain! (road 66)
5.2 – How Naughty Dog makes sure you still see their cool views!
A dedicated button!
With a press on a button (L3), they allow the camera to momentarily reposition itself, aiming at the focal point. Using this method, the developers have total control on what they want the player to see.
6.1 – Demonstration: Flow Gone Wrong, how to recognize the designers intentions. The good, the bad.
To demonstrate on how you can used your now new profound knowledge to recognize flow elements in other games, I will dissect a level section in Uncharted 4. (Chapter 2: Infernal Place)
Something to keep in mind: Nathan doesn’t have a map, he doesn’t use a compass. What a badass.
Video by: Moghi plays (fragment: 8.49 – 10:50)
Steps performed by the player:
The player sees a tower and grapple hook his way towards it.
He proceeds to climb up the tower with use of the grooves.
Climbs inside of the tower.
Walks around the plateau.
Falls in the ocean, trying to find a pathway.
Re-spawn
Can you recognize what goes “wrong” in this small section? What do you think caused the confusion by the player to suddenly fall off the map, into the ocean? Was the player misinformed, weren’t there enough flow elements?
To my observation, they placed a lot of flow elements to guide the player but because of a few poorly placed assets. It unintentionally outweighed the other flow elements placed by the designers.
The cues that should had helped the player
This wooden bar seemed to afford to be hooked. It doesn’t, but it does points towards the objective.
Direction & Shape Language
A pointy triangular rock. Points & triangles can be seen as arrows, arrows indicate direction. In this case this rock is telling us to go upwards.
These grooves have a light yellow rim. In example 2.3, I explained that Uncharted 4 likes to use color to indicate towards the player, that it affords something.
Text & Speech
Nathan knows something you don’t know. “Onward and Upward” he says. He hints to keep going up. This is a critical cue that gets triggered a bit late.
Summarized
With so many flow elements, the player shouldn’t had to be confused right?
The reason for the confusion was likely because of two elements.
The doorway
The wooden balcony
When we convert the picture to black and white, we can see that the difference in contrast makes your eyes focused on the doorway and the wooden plateau.
The doorway affords to be walked through, gates are strong methods of guiding the player. They have a strong attraction to them. You want to walk through it to see whats on the other side. The imbalance between the contrast in shape, lighting and color made the doorway and wooden board pop out more than intended.
A solution?
A potential solution to this problem would be to highlight the grooves a bit more. With use of decals, color or by perhaps destroying part of the construction. Any kind of additional indication that tells the player that they can climb the tower.
But nonetheless, without applying my potential solution. You can also jump of the cliff and the game would re-spawn you on a spot with a nice view of the wooden bar. It almost seems like they intended you to struggle.
Is this the real reason?
It almost seems like they intended you to struggle.
Another theory of mine is that the designers at Naughty Dog planned this all along and this part was supposed to play out like this, to slow down the pacing of the player. Showing them that it is important to look around the environment to find clues. There are really uncountable ways to guide your players.
Disclaimer: At the time of writing this article, I am a 4th year level design student at the Breda University of Applied Science (NHTV). I have no affiliation with Naughty Dog. This article is my own view on their awesome level design. Thanks for reading!
It’s been a long time coming, but we’re excited to finally announce that our neon-soaked arena brawler Hyper Jam will launch February 12 on Xbox One.
The inspiration for Hyper Jam came from many different sources spanning music, film, art and other games, which have all come together to make the game what it is today. And with its dynamic perk drafting system that makes each match different from the last.
An example of this is our perk drafting mechanics, which were inspired by games such as Risk of Rain and Binding of Isaac where you never know how your character will end up at the end of each game, which is an element we wanted to explore within the context of competitive multiplayer instead of the usual Rougelite format. As soon as we played our first prototype, we knew we were onto something special!
Other inspirations include the team’s love for Synthwave, which we would often listen to in the office while making our initial prototypes, and eventually became the primary theme of the game. It’s amazing to be able to feature many of the artists we listened to while working on the game as part of the official Hyper Jam soundtrack.
We are only a small team but have been pouring everything we’ve got into this game over the past few years, transforming Hyper Jam from a humble prototype into a fully-fledged game with cross-platform online multiplayer.
We’re very proud of what we’ve managed to achieve so far and can’t wait for everyone to be able to play Hyper Jam together at last!
We’ve just rolled out an update that makes it easier to find downloadable content for your favorite games. Any game that offers DLC will now have a sortable, featured page of all of its DLC in one place. Furthermore, (and especially for games that have a tons of DLC) we’re providing ways for developers to customize how these pages by creating lists, adding branding and specifying which titles to feature.
Posted by: xSicKxBot - 01-14-2019, 08:15 AM - Forum: Lounge
- No Replies
Unity Disputes Accusations Of Crippling Games; Fortnite Studio Gets Involved
Update 3: In a surprising announcement, Fortnite studio Epic Games announced that it had teamed up with Improbable to create a $25 million fund aimed at encouraging developers to leave Unity in favour of other platforms. Epic and Improbably created the fund to give cash to developers who abandon Unity for other game-development tools. Epic, of course, owns and operates the very popular Unreal Engine, which competes directly with Unity.
"To assist developers who are left in limbo by the new engine and service incompatibilities that were introduced today, Epic Games and Improbable are together establishing a US $25,000,000 combined fund to help developers transition to more open engines, services, and ecosystems," Epic Games CEO Tim Sweeney and Improbable executive Herman Narula said in a joint statement. "This funding will come from a variety of sources including Unreal Dev Grants, Improbable developer assistance funds, and Epic Games store funding."
It continues:
"We believe we are at the beginning of an unprecedented age of inclusive online games that become parts of our everyday lives. Enabling this will take much more than Epic or Improbable; it will take a vastly more mature, broad-based industry to enable this future: a community of companies connected by values such as fair and openly disclosed business terms, respect for developer choice, and full interoperability between platforms, software, and services. We encourage others with a similar vision to reach out, so we can find ways to make it come sooner."
Update 2: Unity has now responded with a blog post of its own that disputes Improbable's account of the situation and states emphatically, "Improbable's blog is incorrect."
Unity offers a detailed breakdown of what's happened over the past year-plus, though it starts out by clarifying, "Projects that are currently in production or live using SpatialOS are not affected by any actions we have taken with Improbable. If a game developer runs a Unity-based game server on their own servers or generic cloud instances (like GCP, AWS or Azure), they are covered by our EULA. We have never communicated to any game developer that they should stop operating a game that runs using Improbable as a service."
It goes on to explain the background of the situation, claiming that despite discussions between the two sides, "Improbable chose an approach which doesn't involve partnering with Unity, but instead involves making unauthorized and improper use of Unity's technology and name in connection with the development, sale, and marketing of its own products. More than a year ago, we told Improbable in person that they were in violation of our Terms of Service or EULA. Six months ago, we informed Improbable about the violation in writing. Recent actions did not come as a surprise to Improbable; in fact, they've known about this for many months."
Unity explains that, two weeks ago, it turned off Improbable's Unity Engine license keys, saying it didn't take the matter lightly but that Improbable had "left us no choice. This was the only course of action to protect the integrity and value of our technology and Unity developers."
"We believe that even though Improbable is violating our EULA, game developers should never pay the price for that," Unity said. "We have been clear with Improbable that games currently in production and/or games that are live are unaffected, and we would have expected them to be honest with their community about this information. Unfortunately, this information is misrepresented in Improbable's blog."
Unity's blog post goes on to provide further details and discuss changes to its EULA. You can read about that in full here. The original story follows.
A dispute between Unity and the developer of the middleware SpatialOS is impacting developers. Studios have had to pull their games due to the conflict, and SpatialOS developer Improbable has strong words for Unity's approach.
In a blog post, Improbable explained that a change in Unity's terms of service puts SpatialOS games in breach of the license terms. In fact, it suggests that Unity clarified directly to the company that the change in the TOS was specifically to disallow services like theirs to work in the Unity engine. It says Unity also revoked the license due to another breach in an unspecified manner. Other engines remain unaffected.
[Update 1: Improbable has now published another blog post in which it accepts some of the blame alongside Unity but suggests the problems are deeper and could have involved any company. It proposes that the games industry "might need to consider making some changes which hugely increase the rate of innovation and the collective success we could all experience." It doesn't outline any specific solutions, instead seemingly seeking to initiate a dialogue on the subject.]
Going forward, Improbable says it is attempting to negotiate with Unity, and is offering development support to those who use the SpatialOS tech in the meantime, including opening an emergency fund. It's also looking into moving to a different engine as a last resort.
"This is an action by Unity that has immediately done harm to projects across the industry, including those of extremely vulnerable or small scale developers and damaged major projects in development over many years," the company said. "Games that have been funded based on the promise of SpatialOS to deliver next-generation multiplayer are now endangered due to their choice of game engine. Live games are now in legal limbo.
"All customers who entered into a relationship with us and Unity previously did so on the good faith understanding that the terms they signed up to, sometimes years ago, would allow them to be successful and not carry additional charges."
Indie developers like Spilt Milk and Vitor de Magalhaes have made announcements on Twitter of their projects going on hiatus, pending a resolution to the conflict.
Posted by: xSicKxBot - 01-14-2019, 02:08 AM - Forum: Lounge
- No Replies
Amazon Is Launching A Game-Streaming Service, Report Says
One of the biggest companies on the planet, Amazon, looks like it's extending its reach to yet another sector. The Information reports today that the retail giant is looking to launch its own game-streaming service. Deadline backed up the report with a report of its own that claims the project exists within Amazon right now.
Deadline also reports that Amazon is currently speaking with publishers to distribute their games on the untitled Amazon game-streaming platform. The service could reportedly launch in 2020 at the earliest, though it's unclear if this is for a beta version of the platform or the full thing.
It appears that streaming could be the next big battleground for game companies. Google already has its Project Cloud game-streaming service that it's testing with Assassin's Creed Odyssey (you can see our impressions in the video above), while Microsoft will let you play Halo on a phone with its Xcloud (working title) streaming service, and Electronic Arts has its own streaming technology in the works under its ridiculously ambitious-sounding Project Atlas. Sony has operated in the game-streaming area for a long time already through its PlayStation Now product.
Amazon already does a lot with games, as the retailer is one of the biggest sellers of games in the world, while it also owns the popular video-streaming site Twitch. Amazon also owns Killer Instinct developer Double Helix, while Amazon has its own game studio team called Amazon Game Studios. In August last year, Amazon announced it had hired 2K Games founder Christoph Hartmann to be the new boss of Amazon Game Studios. it hasn't been all smooth sailing, however, as Amazon Game Studios canceled one of its first games, Breakaway, and a number of high-profile staffers quit.
Amazon Game Studios has a number of games in the works, including a sandbox MMO called New World, the third-persons shooter Crucible, and a game based on Amazon's Grand Tour series.
Streaming is an exciting opportunity for games, and it could spell trouble for hardware manufacturers like PlayStation, Xbox, and Nintendo. In a streaming world, games would play off computers in data centers and stream to your computer or mobile device, which in turn would reduce the need to own a console like an Xbox or PlayStation. One potential issue with streaming is that it depends significantly on network availability and speed, which is no guarantee in some places around the world.
Andrew Wilson, the CEO of EA, said during a presentation recently that he sees a future where you can play games on any device you want, with streaming/cloud gaming help accelerate that shift. Strauss Zelnick, the CEO of Rockstar Games parent company Take-Two Interactive, has said he believes streaming will help accelerate the industry's transition away from "closed" systems.
Video game streaming hasn't been a total success story so far, as you may recall the OnLive service shut down before it ever got much of a foothold. However, given that some of the biggest companies in the world are now investing in game-streaming, it might finally be time for streaming to truly kick off in earnest.
First 4 Figures Teases Its Menacing Metroid Prime Meta Ridley Statue
Ridley has made a comeback in recent years. After finally being added to the Super Smash Bros. series as a playable fighter in the Switch version of the game, First 4 Figures is now teasing the antagonist’s upcoming statue, based on his meta form featured in the Metroid Prime series.
The short clip below reveals reservations will open on Friday (we’re guessing that’s next week) and there’ll also be a ‘Q&A’ on 18th January. There are no other details to share about this statue at this point in time, but as with all F4F releases, it’ll likely require you to empty out every penny in your wallet if you do want it. Take a look at the brief teaser below:
Have you ever wanted a large and expensive Meta Ridley statue in your house? Tell us below.
God Of War, Spider-Man Lead DICE Awards; Here's All The Nominees
The 22nd annual D.I.C.E. Awards have announced the full list of nominees for this year, and Sony's God of War leads the way with 12 total nominations, including a nod for overall Game of the Year. The other Game of the Year nominees are Red Dead Redemption 2, Into the Breach, Spider-Man, and Return of the Obra Dinn.
God of War already won the Game of the Year award at The Game Awards back in December. It is also nominated for a top writing award at the Writers Guild Awards.
Fifty-six games in all received nominations this year. As mentioned, God of War led the way with 12 nominations, while Spider-Man picked up 11. Red Dead Redemption 2 grabbed eight nominations, while Return of the Obra Dinn picked up six.
The winners will be announced during the awards ceremony in Las Vegas on February 13, starting at 8 PM PT / 11 PM ET. Also during the event, Halo boss Bonnie Ross will be honoured as this year's Hall of Fame recipient.