Unreal Engine 5 Game Development with C++ Scripting: Become a professional game developer and create fully functional, high-quality games 1st Edition Zhenyu George Li - Experience the full ebook by downloading it now
Unreal Engine 5 Game Development with C++ Scripting: Become a professional game developer and create fully functional, high-quality games 1st Edition Zhenyu George Li - Experience the full ebook by downloading it now
com
OR CLICK HERE
DOWLOAD EBOOK
https://ebookmeta.com/product/advanced-unity-game-development-build-
professional-games-with-unity-c-and-visual-studio-victor-g-brusca/
ebookmeta.com
https://ebookmeta.com/product/our-living-tradition-first-series-1st-
edition-claude-bissell/
ebookmeta.com
Demon Huntress 1st Edition Milly Taiden
https://ebookmeta.com/product/demon-huntress-1st-edition-milly-
taiden-3/
ebookmeta.com
https://ebookmeta.com/product/lonely-planet-colombia-10th-edition-
lonely-planet/
ebookmeta.com
https://ebookmeta.com/product/leading-from-the-edge-of-the-inside-
embracing-the-heart-of-business-leadership-jim-moats/
ebookmeta.com
https://ebookmeta.com/product/haxe-game-development-essentials-1st-
edition-jeremy-mccurdy/
ebookmeta.com
https://ebookmeta.com/product/colorado-cold-case-1st-edition-elle-
james/
ebookmeta.com
Complete Calisthenics 2nd Edition The Ultimate Guide to
Bodyweight Exercise Ashley Kalym
https://ebookmeta.com/product/complete-calisthenics-2nd-edition-the-
ultimate-guide-to-bodyweight-exercise-ashley-kalym/
ebookmeta.com
Unreal Engine 5
Game Development
with C++ Scripting
Zhenyu George Li
BIRMINGHAM—MUMBAI
Unreal Engine 5 Game Development with C++ Scripting
Copyright © 2023 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted
in any form or by any means, without the prior written permission of the publisher, except in the case
of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information
presented. However, the information contained in this book is sold without warranty, either express
or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable
for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and
products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot
guarantee the accuracy of this information.
ISBN 978-1-80461-393-1
www.packtpub.com
Foreword
I have known and worked with George Li in various capacities for more than 20 years.
We met first as colleagues at a private college of interactive arts in downtown Vancouver, Canada. I
was a full professor of linguistics at a university in the area, with extensive experience in developing
a cognitive science program at the university. Establishing a curriculum for such a program involved
familiarizing myself with areas well beyond the area of my specific academic position and collaborating
closely with colleagues – particularly in computing science (cognitive), psychology, and philosophy
(particularly concerning socio-epistemological issues such as AI). It was in this spirit that I was happy
to associate myself with a private college, focusing on language study and teaching, together with
preparing students to handle 3D computer applications (e.g., 3ds Max, 3D GameStudio, and Unreal)
and showing them how to generate animation materials for film, TV, and games.
George Li was in charge of all the technical requirements of the college. I very quickly realized that he
was not merely extremely competent and forthcoming (he had already occupied high-level computing-
related positions, software engineering for instance, in China prior to emigrating to Canada) but
also computationally competent and brilliantly innovative. He also had a particular interest in the
development of game engines and was already collaborating with his colleague, Charles Yeh, on a
practical reference book, XNA PC & Xbox360 C# Game Programming, with proprietary-produced
text and games to his credit.
As colleagues in the college, George and I found common, mutually strengthening interests. Eventually,
he and I found ourselves in charge of creating a two-year interactive-arts program curriculum for
the college.
My whole career, at universities in the UK and Canada, and as a member of the editorial boards of
a major academic journal and a very influential series, has closely involved the evaluation of the
intellectual quality of people’s capabilities and work, and in my opinion, George Li’s innate talents
shine out clearly throughout his work and will continue to do so in the future. His ability to express
his knowledge of the subject at hand is outstandingly demonstrated in all his work, performance,
expressions, and character.
This book, like the one co-authored with Yeh, is designed for independent developers and company
training, plus for reference after post-secondary education. The knowledge presented herein is most
intelligently, clearly, and effectively presented so as to be as efficiently applicable and pedagogically
effective as possible on any device or platform, producing high-quality games, accessories, and edits.
This volume will certainly stand the test of time and fulfill the majority of the needs of those working
in the field of gaming. However, I am certain that George will make further, very crucial contributions
to this topic.
Until then, this volume will serve you excellently, helping you enjoy and prosper with your future
activities and products.
I express my gratitude to my wife, Alison Guo, for her support in handling family responsibilities and
for enabling me to dedicate time to completing this book. I also extend my thanks to Sarah Beck and
Willy Campos for their encouragement and support throughout the writing process.
About the reviewers
Aditya Dutta holds a game programming advanced diploma from Humber College and is a highly
accomplished senior software engineer at Archiact Interactive, bringing expertise in Unreal Engine
and C++ system design and implementation.
With a strong collaborative spirit, Aditya leads feature development and takes ownership of tools
while actively improving team processes. These leadership skills were evident during his tenure
as lead programmer at Humber College, where he successfully guided and mentored a team of
programmers, overseeing the technical aspects of significant projects in the virtual production and
architecture industries.
His contributions at UP360 Inc. as a programmer included shipping numerous training VR simulations,
developing iterative tools, and implementing gameplay mechanics using Unreal Engine.
Michael Oakes is a senior software consultant for Unity and has over 27 years of experience in the
IT industry. He has worked with real-time 3D and games for over eight years, specializing in mixed
reality design and development, shader programming, and AI and multiplayer systems.
He has worked as a technical consultant on other titles, including Packt Publishing’s Learn ML-Agents
– Fundamentals of Unity Machine Learning, written by Micheal Lanham.
Table of Contents
Part 1 – Getting Started with Unreal C++
Scripting
1
Creating Your First Unreal C++ Game 3
Technical requirements 3 Ensuring your UE has the source code installed 9
Understanding C++ scripting in Unreal 4 Launching the UE5 editor through the Epic
Games Launcher 10
What is the difference between C++ and
Creating the MyShooter C++ project 10
Blueprint?4
Associating VS with UE5 as the default source
When do you use C++? 5
code editor 12
What is the difference between C++
Opening the C++ source code in VS (optional) 13
programming and C++ scripting? 5
2
Editing C++ Code in Visual Studio 21
Technical requirements 21 Solution Explorer 26
Launching VS 22 Output window 27
Error List window 28
Walking through the VS IDE’s UI 24
Code editor 25 Editing code in VS 29
Menus26 Controlling the caret (input cursor) 30
Search box 26 The text editing keys 30
Toolbar26 Code selection 30
viii Table of Contents
3
Learning C++ and Object-Oriented Programming 43
Technical requirements 44 Working on the improved calculator
What is C++? 44 program66
Exploring the C++ program structure 45 Creating references and pointers 72
Defining C++ functions 46 References73
Pointers74
Defining functions with or without parameters 47
Calling functions 47 Understanding OOP 74
Writing the main() function 47 What is OOP? 75
Working with a basic calculator What are classes and objects? 75
program48 Creating classes in C++ 76
Creating objects in C++ 77
Learning the C++ syntax 49
Using the C++ data types 50 Working on an OOP calculator
Defining variables 51 program78
Using C++ arrays 52 Adding constructor and getter functions for
Using C++ operators 53 the calculator class 83
Accepting user input 57 Creating the CalculatorEx class, which
Adding C++ comments 57 inherits from the Calculator class 84
Controlling the C++ flow 58 Summary88
4
Investigating the Shooter Game’s Generated Project and C++ Code 89
Technical requirements 89 Getting familiar with the source code 95
Understanding the MyShooter C++ MyShooterCharacter.h95
project structure 90 MyShooterCharacter.cpp100
Understanding the game program MyShooterProjectile.h and
structure92 MyShooterProjectile.cpp103
Table of Contents ix
Using the UFUNCTION macro 132 Using the Cast template function 145
The UFUNCTION syntax 132 Summary147
UFUNCTION specifiers and metadata keys 132
Tagging ADefenseTower and APlayerAvatar
member functions as UFUNCTION macros 133
6
Creating Game Actors 149
Technical requirements 149 Replacing the game’s player pawn 160
Setting up the player avatar 150 Creating the player avatar’s
Adding SpringArmComponent and animation blueprint 162
CameraComponent to PlayerAvatar 150 Creating the PlayerAvatarAnimInstance class 163
Initializing the player avatar 154 Creating the ABP_PlayerAvatar blueprint 169
Setting up the character’s Creating the State Machine on ABP_
SkeletalMeshComponent155 PlayerAvatar171
Syncing the movement speed with the
Importing the character model 155
animation instance 174
Using the Hero skeletal mesh in BP_
PlayerAvatar160 Summary176
7
Controlling Characters 179
Technical requirements 180 Implementing the OnStateAnimationEnds
function186
Controlling the player character to
attack180 Destroying actors 187
Adding the Attack action to the action map 180 Creating the enemy character 189
Binding the handler function to the Attack Creating the Enemy class 190
action181
Creating the EnemyController class 195
Implementing the OnAttackPressed() action
Creating the ABP_Enemy animation blueprint 200
handler function 182
Creating the BP_Enemy blueprint 201
Implementing the CanAttack() and Attack()
functions182 Testing the game 203
Processing non-loop animations 184 Summary204
8
Handling Collisions 205
Technical requirements 205 Using collisions for game interactions213
Understanding collision detection 206 Downloading and creating the weapon,
defense tower, and fireball actors 214
Setting the collision presets 210
Table of Contents xi
9
Improving C++ Code Quality 239
Technical requirements 239 Creating a fireball pool 256
Refactoring code 240 Outputting debug messages 263
Combining the PlayerAvatarAnimInstance Using the UE_LOG macro 264
and EnemyAnimInstance classes 240 Printing debug messages to the screen 265
Making PangaeaCharacter the parent class of
APlayerAvatar and AEnemy 243 Checking an Actor instance’s actual
class type 266
Refining code 255
Summary269
Using caching variables 255
11
Controlling the Game Flow 295
Technical requirements 295 Adding the Timer variable to the
APangaeaGameState class 313
Designing the Pangaea game’s flow 296
Making the Timer variable replicable 314
Creating the UI widgets 297
Defining OnTimeChangedDelegate 314
Creating BP_LobbyWidget 298
Creating and binding the custom event to
Creating BP_HUDWidget 301 OnTimeChangedDelegate315
Creating BP_GameOverWidget 303 Counting down the timer 317
Adding networking functions to Designating APangaeaGameState as the
PangaeaGameInstance306 project’s game state class 319
12
Polishing and Packaging the Game 327
Technical requirements 327 Packaging the game 338
Polishing the game 328 Configuring the project settings for packaging 338
Importing and using high-quality game assets 328 Making the build a windowed game 340
Fixing bugs 331 Avoiding the hardcoded path for finding
Profiling and optimization 331 content341
Packaging the project 344
Using Unreal Engine console
commands332 What to do next 347
Exploring modes and console commands 332 Summary348
Executing console commands in C++ 336
Index349
As an Unreal Engine developer, you may have a genuine interest in understanding C++ and how it
integrates with the engine, even if you don’t identify as a software engineer or aspire to become one.
This book is designed to assist you in expanding your knowledge and skills by guiding you through
the necessary steps to create a fully fledged game, covering essential aspects of game development. It
aims to smoothen the learning curve, allowing for a more seamless and efficient grasp of the concepts
presented. The carefully organized topics eliminate the need for random searching and prevent wasted
time on unrelated readings, enabling you to focus on the relevant information. Moreover, this book
serves as a valuable reference manual, offering a comprehensive resource that can be revisited and
utilized for further study.
• Non-engineer game developers, such as game designers and artists who aspire to learn and
comprehend C++ in the context of Unreal Engine development
• Software engineers who may lack prior experience in Unreal Engine C++ programming but
wish to quickly acquire the necessary skills for their next project or job
• Students who are interested in learning and digging into Unreal C++ programming for their
study or personal projects
• Individuals with a keen interest in game development using Unreal Engine will benefit from
the comprehensive knowledge presented within these pages
Chapter 8, Handling Collisions, discusses the engine’s collision system and its configurations for game
interactions. To handle collision events – attack hits and projectile hits, for example – you will learn
how to configure actor colliders and triggers. Using ray casts to check whether a projectile hits the
target is also introduced in this chapter.
Chapter 9, Improving C++ Code Quality, presents how to employ software engineering practices during
code refactoring and refinement. This chapter implements class generalization, caching, and pooling
methods to improve the game code’s quality and performance.
Chapter 10, Making Pangaea a Network Multiplayer Game, starts by introducing the fundamental
concepts related to multiplayer games, including servers, clients, and multiplayer modes. You will
be guided step by step through converting the single-player Pangaea game into a multiplayer game.
Chapter 11, Controlling the Game Flow, intends to make Pangaea a complete multiplayer game, which
has a main menu as the lobby, so that players can decide whether they want to start a host or join
a game session. C++ and Blueprint scripting skills for user interface operations are also revealed in
this chapter.
Chapter 12, Polishing and Packaging the Game, provides resources, methods, and suggestions on how to
polish games from both visual experience and product quality aspects. This chapter also provides steps
for configuring and packaging the Pangaea project to be an executable standalone game for distribution.
If you conduct experiments with the samples on systems other than Microsoft Windows, such as
macOS, please keep in mind that there may be user interface and configuration differences that may
not be addressed in this book.
If you are using the digital version of this book, we advise you to type the code yourself or access
the code from the book’s GitHub repository (a link is available in the next section). Doing so will
help you avoid any potential errors related to the copying and pasting of code.
We also have other code bundles from our rich catalog of books and videos available at https://
github.com/PacktPublishing/. Check them out!
Conventions used
There are a number of text conventions used throughout this book.
Code in text: Indicates code words in text, database table names, folder names, filenames,
file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example:
"The AProjectile class can be inherited as child classes for creating various fireable objects, such as
AFireBall, AMissile, ABomb, and so on."
A block of code is set as follows:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DefenseTower.generated.h
When we wish to draw your attention to a particular part of a code block, the relevant lines or items
are set in bold:
void APangaeaCharacter::BeginPlay()
{
…
_AnimInstance = Cast<UPangaeaAnimInstance>(
GetMesh()->GetAnimInstance());
…
}
$ mkdir css
$ cd css
Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in
menus or dialog boxes appear in bold. Here is an example: "In the Unreal Project Browser window,
choose the GAMES tab on the left side. Then select the First Person template."
Additionally, the C++ sample code provided in this book adheres primarily to Unreal Engine’s coding
standard, ensuring consistency and minimizing confusion for readers. For detailed information, you
can visit the official Code Standard website here: https://docs.unrealengine.com/5.0/
en-US/epic-cplusplus-coding-standard-for-unreal-engine/.
Exceptions may occur when using compact expressions that are clear and easily understood, allowing the
text to fit within the constraints of the page printing layout without compromising reader comprehension.
For example, the following line of code follows the code standard by explicitly declaring the type of
the assigned GameInst variable:
Get in touch
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, email us at
[email protected] and mention the book title in the subject of your
message.
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen.
If you have found a mistake in this book, we would be grateful if you would report this to us. Please
visit www.packtpub.com/support/errata and fill in the form.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would
be grateful if you would provide us with the location address or website name. Please contact us at
[email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you
are interested in either writing or contributing to a book, please visit authors.packtpub.com.
xviii
https://packt.link/free-ebook/9781804613931
In this part, the primary focus will be on providing an introduction to the basics of C++ programming,
specifically for game development with Unreal Engine. You will gain knowledge on creating a C++
game project in Unreal, as well as utilizing MS Visual Studio to access and modify the game’s source
code. Moreover, essential concepts of C++ and object-oriented programming, along with their syntax,
will be introduced. Building upon this foundation, we will examine the generated source code to
conduct an initial investigation into the game project.
This part contains the following chapters:
Technical requirements
As a reader of this book, you will be expected to have common computer operational skills. You
should also have basic knowledge of and experience with the UE5 editor, as well as some Blueprint
scripting skills.
To follow this chapter, you should have installed Epic Games Hub and the 5.03 or later version of
the engine editor on your computer. If you haven’t done so, please go to the official Epic website
(https://www.unrealengine.com/en-US) to register an account and download the Epic
Games Launcher.
4 Creating Your First Unreal C++ Game
C++ code and files can be well-organized based on an entire project’s mechanics. It is easy to globally
search, locate, and access code blocks to edit, maintain, and troubleshoot. In the meantime, it is also
easier to read and understand a big chunk of code that implements complex algorithms and logic.
Blueprint, on the other hand, is a context-sensitive scripting environment. Blueprint graphs are
relatively independent. When a graph needs to solve complex logic, the nodes and the connection
lines create messy spaghetti that can hardly be understood and maintained.
C++ also has some shortcomings. One example is that it may cause critical errors that may crash an
entire system. That is usually caused by the developer’s mistakes. Since Blueprint is a protected layer,
it is safer, and hence, the chances of the system crashing are fewer.
In conclusion, the choice between C++ and Blueprint should be made based on specific development
requirements and conditions, considering the pros and cons of each approach.
• Performance
• Logic and algorithm complexity
• Accessibility to a system’s core functions
• The developer’s experience
If you want higher performance and deal with advanced game logic and system processes, and you
are capable of coding and solving complex problems, you should go for C++.
C++ programming means using the C++ programming language to write code for any purpose; it
doesn’t have to be just for UE projects. C++ scripting, in this book, is a specific dialect of the C++
programming language supported by the UE. It takes advantage of the power of C++ syntax and also
works with UE’s Application Programming Interfaces (APIs), which allow developers to create and
extend the engine’s functionalities for their games and the development environment’s context, such
as objects, graphics, audio, and network communication.
Now that we have a basic overview of C++ and have learned why and when to use C++ for Unreal
game developments, let’s dive deeper into C++ scripting by creating a sample project.
Note
To install VS, a Microsoft account is typically required. If you don’t have a Microsoft account, you
can register using the following page: https://account.microsoft.com/account/.
Next, launch VisualStudioSetup.exe inside the folder where you downloaded the VS installer
(the \Downloads folder, for example).
Enable the two Game development with C++ and Desktop development with C++ checkboxes –
these two options tell the installer to install the C++ compiler and the professional game development
support for UE (see Figure 1.2).
8 Creating Your First Unreal C++ Game
Also, keep an eye on the following options on the Installation details panel that belongs to the Desktop
development with C++ group, and make sure the following are checked:
Then, click the Install button to install the workloads and reboot the system, and then you will see a
prompt from the dialog popup (see Figure 1.3):
The next thing we need to do is to confirm that we have installed the engine source code together
with the UE5 editor. The reason why we need this is that when we generate a new project, the engine
source code can be integrated into the new project; under certain circumstances, we may need to
modify or customize the engine for the game’s specific needs.
1. Click the downward arrow button and choose Options from the drop-down menu.
2. Make sure that the Engine Source option is checked.
3. Press the Apply button:
UE is an ongoing development product, with bugs and defects that may need to be fixed by its users.
Also, professional developers sometimes modify the engine source code to adapt to their specific
needs. An example of this is when we face an issue with geometry instancing (or instanced rendering)
working only in the game’s development build but not in the release build, which is subsequently
resolved by our engineer modifying the engine’s source code.
10 Creating Your First Unreal C++ Game
Note
Geometry instancing is a rendering technique that renders multiple instances of a visual object
in a single draw call and provides each instance with some unique attributes: https://
en.wikipedia.org/wiki/Geometry_instancing.
We are now ready to start the UE editor through the Epic Games Launcher.
Figure 1.5 – Launching the UE5 editor from the Epic Games Launcher
The next thing we want to do is to create a new game project. Let’s name the new project MyShooter.
1. In the Unreal Project Browser window, choose the GAMES tab on the left side.
2. Select the First Person template.
3. Select the C++ button.
Creating your C++ Shooter project from a template 11
4. Choose the project location (for example, C:\UEProjects) and type MyShooter in the
Project Name field.
5. Click the Create button.
The created game project also includes the starter content, which is packaged with assets and resources
that can be used to prototype the game.
The engine will do some initialization work and then open the editor when things are ready. If you
look at the project tree panel’s MyShooter tab in the bottom-left corner of the editor window, you
should see the C++ Classes node on the same layer as the Content node (see Figure 1.7).
12 Creating Your First Unreal C++ Game
Figure 1.7 – The MyShooter C++ project opened in the UE5 editor
The system will automatically launch VS, and the VS editor will open the MyShooterCharacter.
cpp file (see Figure 1.10).
14 Creating Your First Unreal C++ Game
Back in the Unreal editor, click the Play ( ) button to start the game. While playing the game on the battlefield,
you can control your character, move them around, and pick up the gun in front of them (see Figure 1.11).
We have learned how to create a UE C++ project from scratch. However, what if we already have a
Blueprint project and want to convert it to a C++ project? UE allows developers to do it by adding a
new C++ class to the project. Let’s practice converting a MyBPShooter Blueprint project.
1. First of all, you have to create a Blueprint project, MyBPShoopter, under C:\UEProjects
(you can choose a different path to create the new project). Use the same steps introduced in
the Creating the MyShooter C++ project section, but choose BLUEPRINT instead of C++ for
the creation of the MyBPShooter project.
2. Secondly, open the new project in UE5. Pay attention to the project tree; it doesn’t have the
C++ Classes node at this stage.
3. Select Tools | New C++ Class from the editor’s main menu, and then, in the Add C++ Class window
(see Figure 1.14), choose Character as the base class (a class that contains common attributes
and methods that are shared by its derived classes) to create the MyShooterCharacter class.
Converting an existing Blueprint project to a C++ project 17
Figure 1.14 – Adding a new C++ class from the Character class
Once you click the Next> button, it will navigate to the NAME YOUR NEW CHARACTER screen.
4. On the NAME YOUR NEW CHARACTER screen, type MyBPShooterCharacter into
the Name field.
Please pay attention to the path where the header and the source files will be placed. They look
different from the MyShooter project because the C++ node hasn’t been created yet. Don’t worry
about it at the moment. Once the conversion job is done, the system will automatically move
the files to the right place.
5. After clicking the Create Class button, you will see a progress bar.
Figure 1.16 – The MyBPShooterCharacter C++ class Adding code to project… progress bar
Wait for the pop-up message, which indicates that the C++ class job has been added.
Figure 1.17 – A message saying that the MyBPShooterCharacter C++ class is now added
6. Click the OK button. Now, you will see the message dialog, which asks you whether you want
to edit the code (see Figure 1.18). Choose No here.
7. Shut down your UE editor and reopen MyBPShooter. When you see a dialog that asks
whether you want to rebuild the project, answer Yes here.
Converting an existing Blueprint project to a C++ project 19
When it is done, you will find the new C++ Classes node on the project tree, and the
MyShooterCharacter class is already placed in the MyBPShooter folder:
You may have noticed that some other files, such as MyBPShooterGameMode are missing, in
comparison with the MyShooter project. That is because the Blueprint versions already exist, so the
corresponding C++ versions are not automatically generated. You can choose to manually convert
those blueprints to C++ classes only when necessary; otherwise, you just keep the blueprints.
Exploring the Variety of Random
Documents with Different Content
he cared nothing for the world’s praise, it was pleasant to know that
his powers were still unimpaired, and be able to laugh in his sleeve
at the deluded critics. That was like him, and it deceived me till to-
day. Now I know that he begrudged me your admiration, wanted
your tears and smiles for himself, and did not hesitate to steal them.
The night he so adroitly read his work for mine, he tempted me
through you. I had resolved to deserve the love and honor you gave
me; and again I tried, and again I failed, for my romance was a
poor, pale thing to his. He had read it; and, taking the same plot,
made it what you know, writing as only such a man could write,
when a strong motive stimulated him to do his best.”
“But why did you submit? Why stand silent and let him do so false a
thing?” cried poor Gladys, wondering when the end of the tangle
would come.
“At first his coolness staggered me; then I was curious to hear, then
held even, against my will, by admiration of the thing—and you. I
meant to speak out, I longed to do it; but it was very hard, while
you were praising me so eloquently. The words were on my lips,
when in his face I saw a look that sealed them. He meant that I
should utter the self-accusation which would lower me for ever and
raise him in your regard. I could not bear it. There was no time to
think, only to feel, and I vowed to make you happy, at all costs. I
hardly thought he would submit; but he did, and I believed that it
was through surprise at being outwitted for the moment, or pity
towards you. It was neither: he fancied I had discovered his secret,
and he dared not defy me then.”
“But when I was gone? You were so late that night: I heard your
voices, sharp and angry, as I went away.”
“Yes; that was my hour, and I enjoyed it. He had often twitted me
with the hold he had on my name and fame, and I bore it; for, till I
loved you, they were the dearest things I owned. That night I told
him he should not speak; that you should enjoy your pride in me,
even at his expense, and I refused to release him from his bond, as
he had, more than once, refused to release me: for we had sworn
never to confess till both agreed to it. Good heavens! how low he
must have thought I had fallen, if I could consent to buy your
happiness at the cost of my honor! He did think it: that made him
yield; that is the cause of the contempt he has not cared to hide
from me since then; and that adds a double edge to my hatred now.
I was to be knave as well as fool; and while I blinded myself with his
reflected light, he would have filched my one jewel from me. Gladys,
save me, keep me, or I shall do something desperate yet!”
Beside himself with humiliation, remorse, and wrath, Canaris flung
himself down before her, as if only by clinging to that frail spar could
he ride out the storm in which he was lost without compass or
rudder.
Then Gladys showed him that such love as hers could not fail, but,
like an altar-fire, glowed the stronger for every costly sacrifice
thrown therein. Lifting up the discrowned head, she laid it on her
bosom with a sweet motherliness which comforted more than her
tender words.
“My poor Felix! you have suffered enough for this deceit; I forgive it,
and keep my reproaches for the false friend who led you astray.”
“It was so paltry, weak, and selfish. You must despise me,” he said,
wistfully, still thinking more of his own pain than hers.
“I do despise the sin, not the dear sinner who repents and is an
honest man again.”
“But a beggar.”
“We have each other. Hush! stand up; some one is coming.”
Canaris had barely time to spring to his feet, when Stern came in,
and was about to pass on in silence, though much amazed to see
Gladys there at that hour, when the expression of the young man’s
face made him forget decorum and stop short, exclaiming, anxiously,
—
“Mr. Felix, what’s the matter? Is master worse?”
“Safe and asleep. Mrs. Canaris came to see what I was about.”
“Then, sir, if I may make so bold, the sooner she gets to bed again
the better. It is far too late for her to be down here; the poor young
lady looks half-dead,” Stern whispered, with the freedom of an old
servant.
“You are right. Come, love;” and without another word Canaris led
her away, leaving Stern to shake his gray head as he looked after
them.
Gladys was utterly exhausted; and in the hall she faltered, saying,
with a patient sigh, as she looked up the long stairway, “Dear, wait a
little; it is so far,—my strength is all gone.”
Canaris caught her in his arms and carried her away, asking himself,
with a remorseful pang that rent his heart,—
“Is this the murder I have committed?”
XVII.
“S tern!”
“Yes, sir.”
“What time is it?”
“Past two, sir.”
“What news? I see bad tidings of some sort in that lugubrious face
of yours; out with it!”
“The little boy arrived at dawn, sir,” answered old Stern, with a
paternal air.
“What little boy?”
“Canaris, Jr., sir,” simpered the valet, venturing to be jocose.
“The deuce he did! Precipitate, like his father. Where is Felix?”
“With her, sir. In a state of mind, as well he may be, letting that
delicate young thing sit up to keep him company over his poetry
stuff,” muttered Stern, busying himself with the shutters.
“Sit up! when? where? what are you maundering about, man?” and
Helwyze himself sat up among the pillows, looking unusually wide-
awake.
“Last night, sir, in the study. Mr. Felix made me go for a wink of
sleep, and when I came back, about one, there sat Mrs. Canaris as
white as her gown, and him looking as wild as a hawk. Something
was amiss, I could see plain enough, but it wasn’t my place to ask
questions; so I just made bold to suggest that it was late for her to
be up, and he took her away, looking dazed-like. That’s all I know,
sir, till I found the women in a great flustration this morning.”
“And I slept through it all?”
“Yes, sir; so soundly, I was a bit anxious till you waked. I found the
glass empty and the bottle smashed, and I was afraid you might
have taken too much of that choral while half-asleep.”
“No fear; nothing kills me. Now get me up;” and Helwyze made his
toilet with a speed and energy which caused Stern to consider
“choral” a wonderful discovery.
A pretence of breakfast; then Helwyze sat down to wait for further
tidings,—externally quite calm, internally tormented by a great
anxiety, till Olivia came in, full of cheering news and sanguine
expectations.
“Gladys is asleep, with baby on her arm, and Felix adoring in the
background. Poor boy! he cannot bear much, and is quite bowed
down with remorse for something he has done. Do you know what?”
As she spoke, Olivia stooped to pick up a book half-hidden by the
fringe of a low chair. It lay face downward, and, in smoothing the
crumpled leaves before closing it, she caught sight of a black and
blotted name. So did Helwyze; a look of intelligence flashed over his
face, and, taking the volume quickly, he answered, with his finger on
the title-page,—
“Yes, now I know, and so may you; for if one woman is in the
secret, it will soon be out. Felix wrote that, and it is true.”
“I thought so! One woman has known it for a long time;
nevertheless, the secret was kept for your sake;” and Olivia’s dark
face sparkled with malicious merriment, as she saw the expression
of mingled annoyance, pride, and pleasure in his.
“My compliments and thanks: you are the eighth wonder of the
world. But what led you to suspect this little fraud of ours?”
“I did not, till the last book came; then I was struck here and there
by certain peculiar phrases, certain tender epithets, which I think no
one ever heard from your lips but me. These, in the hero’s mouth,
made me sure that you had helped Canaris, if not done the whole
yourself, and his odd manner at times confirmed my suspicion.”
“You have a good memory: I forgot that.”
“I have had so few such words from you that it is easy to remember
them,” murmured Olivia, reproachfully.
It seemed to touch him; for just then he felt deserted, well knowing
that he had lost both Felix and Gladys; but Olivia never would desert
him, no matter what discovery was made, or who might fall away.
He thanked her for her devotion, with the first ray of hope given for
years, as he said, in the tone so seldom heard,—
“You shall have more henceforth; for you are a staunch friend, and
now I have no other.”
“Dear Jasper, you shall never find me wanting. I will be true to the
death!” she cried, blooming suddenly into her best and brightest
beauty, with the delight of this rare moment. Then, fearing to
express too much, she wisely turned again to Felix, asking curiously,
“But why did you let this young daw deck himself out in your
plumes? It enrages me, to think of his receiving the praise and
honor due to you.”
He told her briefly, adding, with more than his accustomed
bitterness,—
“What did I want with praise and honor? To be gaped and gossiped
about would have driven me mad. It pleased that vain boy as much
as fooling the public amused me. A whim, and, being a dishonest
one, we shall both have to pay for it, I suppose.”
“What will he do?”
“He has told Gladys, to begin with; and, if it had been possible,
would have taken some decisive step to-day. He can do nothing
sagely and quietly: there must be a dramatic dénouement to every
chapter of his life. I think he has one now.” Helwyze laughed, as he
struck back the leaves of the book he still held, and looked at the
dashing signature of his own name.
“He wrote that, then?” asked Olivia.
“Yes, here, at midnight, while I lay asleep and let him tell the tale as
he liked to Gladys. No wonder it startled her, so tragically given. The
sequel may be more tragic yet: I seem to feel it in the air.”
“What shall you do?” asked Olivia, more anxiously than before; for
Helwyze looked up with as sinister an expression as if he knew how
desperate an enemy had stood over him last night, and when his
own turn came, would be less merciful.
“Do? Nothing. They will go; I shall stay; tongues will wag, and I shall
be tormented. I shall seem the gainer, he the loser; but it will not be
so.”
Involuntarily his eye went to the little chair where Gladys would sit
no longer, and darkened as if some light had gone out which used to
cheer and comfort him. Olivia saw it, and could not restrain the
question that broke from her lips,—
“You do love her, Jasper?”
“I shall miss her; but you shall take her place.”
Calm and a little scornful was his face, his voice quite steady, and a
smile was shed upon her with the last welcome words. But Olivia
was not deceived: the calmness was unnatural, the voice too steady,
the smile too sudden; and her heart sank as she thanked him,
without another question. For a while they sat together playing well
their parts, then she went away to Gladys, and he was left to several
hours of solitary musing.
Had he been a better man, he would not have sinned; had he been
a worse one, he could not have suffered; being what he was, he did
both, and, having no one else to study now, looked deeply into
himself, and was dismayed at what he saw. For the new love, purer,
yet more hopeless than the old, shone like a star above an abyss,
showing him whither he had wandered in the dark.
Sunset came, filling the room with its soft splendor; and he watched
the red rays linger longest in Gladys’s corner. Her little basket stood
as she left it, her books lay orderly, her desk was shut, a dead flower
drooped from the slender vase, and across the couch trailed a soft
white shawl she had been wont to wear. Helwyze did not approach
the spot, but stood afar off looking at these small familiar things
with the melancholy fortitude of one inured to loss and pain. Regret
rather than remorse possessed him as he thought, drearily,—
“A year to-morrow since she came. How shall I exist without her?
Where will her new home be?”
An answer was soon given to the last question; for, while his fancy
still hovered about that nook, and the gentle presence which had
vanished as the sunshine was fast vanishing, Canaris came in
wearing such an expression of despair, that Helwyze recoiled, leaving
half-uttered a playful inquiry about “the little son.”
“I have no son.”
“Dead?”
“Dead. I have murdered both.”
“But Gladys?”
“Dying; she asks for you,—come!” No need of that hoarse command;
Helwyze was gone at the first word, swiftly through room and hall,
up the stairs he had not mounted for months, straight to that
chamber-door. There a hand clutched his shoulder, a breathless
voice said, “Here I am first;” and Canaris passed in before him,
motioning away a group of tearful women as he went.
Helwyze lingered, pale and panting, till they were gone; then he
looked and listened, as if turned to stone, for in the heart of the
hush lay Gladys, talking softly to the dead baby on her arm. Not
mourning over it, but yearning with maternal haste to follow and
cherish the creature of her love.
“Only a day old; so young to go away alone. Even in heaven you will
want your mother, darling, and she will come. Sleep, my baby, I will
be with you when you wake.”
A stifled sound of anguish recalled the happy soul, already half-way
home, and Gladys turned her quiet eyes to her husband bending
over her.
“Dear, will he come?” she whispered.
“He is here.”
He was; and, standing on either side the bed, the two men seemed
unconscious of each other, intent only upon her. Feebly she drew the
white cover over the little cold thing in her bosom, as if too sacred
for any eyes but hers to see, then lifted up her hand with a
beseeching glance from one haggard face to the other. They
understood; each gave the hand she asked, and, holding them
together with the last effort of failing strength, she said, clear and
low,—
“Forgive each other for my sake.”
Neither spoke, having no words, but by a mute gesture answered as
she wished. Something brighter than a smile rested on her face,
and, as if satisfied, she turned again to Canaris, seeming to forget all
else in the tender farewell she gave him.
“Remember, love, remember we shall be waiting for you. The new
home will not be home to us until you come.”
As her detaining touch was lifted, the two hands fell apart, never to
meet again. Canaris knelt down to lay his head beside hers on the
pillow, to catch the last accents of the beloved voice, sweet even
now. Helwyze, forgotten by them both, drew back into the shadow
of the deep red curtains, still studying with an awful curiosity the
great mystery of death, asking, even while his heart grew cold within
him,—
“Will the faith she trusted sustain her now?”
It did; for, leaning on the bosom of Infinite Love, like a confiding
child in its father’s arms, without a doubt or fear to mar her peace, a
murmur or lament to make the parting harder, Gladys went to her
own place.
XVIII.