An Excerpt from “Families of Empire”

I’ve mentioned working on my next novel in prior posts. It will be titled “Families of Empire” and focus on a young man who plays a larger role than is believed by his friends and peers.

Today, I’ll share an excerpt from about mid-way through the story. Hopefully, having an introduction to the main character (Cosimo) and some of the culture and conflict in the story will help make sense of my prior ramblings on writing this tale and whet your appetite for a read once it is fully published.


“You look as bored as I feel,” a warm, soft voice said next to me. I glanced, appreciating her sharp profile in the dim light of the balcony, and smiled.

“I’m just taking a break from being a social butterfly,” I said. “This is my sixth gala in ten days, and I feel like I’ve talked my throat raw.”

“But you’ve only shaken my hand and said what a pleasure it was to meet me,” she teased.

“That was eight days ago. I was trying to choose my follow-up line, but knew I’d be tongue-tied if I approached.”

She laughed. It was a throaty chuckle more than a solid guffaw, but it suited her. “You are charming despite being so shy,” she teased back. “Since I approached you, I guess you don’t have to be tongue-tied now.”

“Miss Dennison, it’s a pleasure to see you again. I’d ask if you are enjoying yourself, but I suspect you are bored with the high season here tonight.”

“Why Cosimo, how could you even hint at such a thing? Beatrice’s mother simply cannot throw a boring gala. That is not allowed. As one of the leading families in the Empire, I’m certain it is the height of entertainment. It must be your simple mind that can’t fathom such lofty performances.” She motioned to the pantomime troupe monopolizing the dance floor below us.

They looked like mimes playing charades with stiffly choreographed movements within their own group. I knew enough ‘modern’ performance art to know that it was the height of fashion, but I could not take the performance seriously. The individuals in the troupe were fit and fluid, moving easily within their play, but the whole lacked any emotional connection for me. I said as much.

“Gods, yes,” Samantha Dennison agreed. “I’d rather see the ballet or even a good cabaret scene than this excrement,” she opined.

I nodded.

She gave me a sideways look. “That was a perfect opening for you to invite me to see one or the other next week,” she said.

I turned to face her. She was a small woman, but perfectly proportioned and attractive. Her head came to just above my shoulder, but her posture and carriage made her seem to be my match. Her self-confidence belied her size. She had dark hair with lighter highlights styled into a delightful cascade of loose curls gathered over one shoulder. Her high cheekbones and rounded nose were a perfect canvas for her full red lips and warm light eyes. She was very attractive, witty, and smart. Of course, she was an aristocrat and all that entailed, which would make my grandmother happy. Her family interests were mostly in the south of the continent, with vast agricultural holdings. Her eldest brother was being groomed to be a senator while her older sisters were being married to other aristocratic and high guilder lines. I wondered if she had chosen me or been launched my direction, given the nature of the social season here in Cardino.

“If only the ballet was performing here next week, I’d be honored to ask to escort you. Alas,” I said dramatically, “there is no performance scheduled.”

Her eyes crinkled as she smiled. “I’ve heard there is to be a dancing exhibition at the club next week. Perhaps that would suit us better than a long ballet.”

I laughed. “My apologies, madame, but I work at that club and can think of better places to spend my off time, no matter how nice the atmosphere or company might be.”

She frowned. I was sorry to hurt her feelings so rushed ahead. “However, I happen to know of a private performance that troupe will have before their scheduled show, if you would care to watch with myself and my grandmother.”

She smiled. “I think I would enjoy that,” she said. “When and where is this private performance?”

“It’s in a private residence, near the club. We can have an early dinner or late lunch afterwards if that suits you.”

She nodded. “My aunt will be wanting to accompany me,” she said as she glanced down to the main floor and spotted her chaperone who had been escorting her to all the balls this season. “Will that be a problem?”

I shook my head. “Not at all. I’ll send you a card to confirm the details.”

She smiled and raised her hand for me to hold and raise to my lips for the briefest of kisses.

“I look forward to seeing you again, Cosimo.”

I felt a shiver in my spine as she locked eyes with me, holding my gaze for a moment, and then turned away.

The social season that made Cardino the place for aristocrats and high-guilders to see and be seen each year ran for six ten-days spanning the last week of spring and the first half of summer. It had been running for about half of its allotted time, and I was more than ready for it to be over. I could play the role my grandmother desired, but I was hardly enamored with it. The season had started with several formal grand balls, then segued into a series of dinners hosted by the upper crust of imperial and local society. Of course, young people being what we were, the club had been doing a tremendous after-dinner business with its wide variety of entertainments. Since ‘the Grande dame’ insisted I attend a minimum of four social engagements each ten-day, I had reduced my classes at the collegium and worked several double shifts managing at the club. Seeing debutantes pretending to be of the highest class at dinner followed by a drunken display hours later at the club had made me more than a little jaded.

I was happy that I could not recall seeing Samantha Dennison in such a state. Of the hundreds of eligible women, I had been maneuvered into spending time with, she was the first that had approached me so subtly, and she had done it herself rather than go through her aunt or my grandmother. Samantha would be one to watch, I decided.

My thoughts were interrupted by applause as the troupe finished their routine. I joined in, glad the debacle was over. I could now make my way back downstairs, thank our hostess and host, and make good my departure. Grandmother had insisted I stay until the entertainment had finished. I had met my obligation to her, and soon completed my false thanks for the wonderful show to meet my social obligation as well. I was turning toward the front hall when a stranger bumped into me.

I felt fingers deftly dance on my lapel and looked at the man closely even as he mumbled an apology and turned away, hurrying before me toward the door. I straightened my jacket, ensuring the small envelope he had deposited was well down inside my pocket, and then followed him at a more sedate pace.

I seemed to have gained another obligation for the evening.


Making Time to Write

As the new year gets started, it has become a challenge to find time to write.  Work takes a lot of time, focus, and writing so the last thing I’m motivated to do is sit down and work on a story at the end of the day.  As part of my ongoing learning journey relating to Generative AI, I figured I’d ask ChatGPT what it would recommend.  Here are it’s suggestions.


Here are five tips to help a new writer make progress on their stories:

1. Set Realistic Goals:

Break down your writing goals into smaller, manageable tasks. Instead of aiming to finish an entire novel in a month, set a goal to write a certain number of words or complete a specific scene each day. This makes the writing process more achievable and less overwhelming.

2. Establish a Writing Routine:

Create a consistent writing routine that fits into your daily life. Whether it’s writing for a set amount of time each day or dedicating specific days to writing, having a routine helps build a writing habit. Consistency is key when it comes to making progress on your stories.

3. Silence Your Inner Critic:

Don’t let your inner critic hold you back. In the early stages of writing, focus on getting your ideas down on paper without worrying too much about perfection. You can always revise and edit later. Allow yourself the freedom to explore and experiment with your writing without the fear of judgment.

4. Join a Writing Community:

Connect with other writers to share experiences, get feedback, and find inspiration. Joining a writing group, either in person or online, can provide valuable support and encouragement. You can learn from others, receive constructive criticism, and stay motivated by being part of a community that shares your passion.

5. Read and Learn Continuously:

Reading widely in various genres exposes you to different writing styles and techniques. Analyze how your favorite authors structure their stories, create characters, and build tension. Additionally, invest time in learning about the craft of writing through books, articles, and workshops. Continuous learning helps you refine your skills and stay motivated.

Remember, writing is a process that involves both creativity and discipline. Celebrate small achievements along the way, stay committed to your writing routine, and don’t be afraid to evolve as a writer. Every word you write is a step toward improving and completing your stories.


The advice seems reasonable. What do you think?

Creating Character Images with Stable Diffusion

I’ve written about using Stable Diffusion after the fact to create images of characters, and shared samples of my results, but did not detail my specific workflow or process, so I thought I’d share a little about it.  I like to let the computer churn out possible images while I’m working on writing or other things.  Depending on how many images I’m running in a batch, reviewing the results can be a nice break and reminder to stand up and stretch.

What is Stable Diffusion?

Stable diffusion both a term of art and a reference to a specific software used to generate images.  As a term of art, it is a concept in mathematics and physics that describes how certain systems evolve over time in a smooth and predictable manner. Imagine a calm river where the flow of water remains steady and uniform. In stable-diffusion, a similar principle applies to various processes, where changes occur gradually and smoothly without sudden disruptions. This concept is often used in fields like statistical mechanics and finance to model the gradual spread or diffusion of quantities such as heat, information, or financial assets. In simpler terms, stable-diffusion helps us understand how things spread or change in a stable and continuous way, much like the steady flow of a tranquil river.

In the context of generating images refers to a method used in machine learning and artificial intelligence to produce high-quality and coherent images. Imagine starting with a vague and blurry image and gradually refining it, step by step, like slowly bringing an out-of-focus picture into clear focus. This technique ensures a smooth and stable transformation of the image, avoiding sudden and jarring changes. In the process, details are added progressively, resulting in realistic and visually appealing images. Stable-diffusion is particularly valuable in image generation tasks as it enables the generation of complex and intricate visual content in a controlled and gradual manner.

For the rest of this blog entry, I will used Stable Diffusion to be the software used to generate images.  The software is developed and maintainted by stability.ai .  You can see the git code repository here.

Introduction to my set-up

I’m running Stable Difussion 1.5 on a Mac Pro with a M2 processor.  I started on an older Intel based Mac, but still followed the same install journey discussed here.  This article covers the installation of the Automatic1111 GUI for use via a browser to manage the generation of images.  The mac specific instructions for installation can be found here. (As of this writing, I’m running version: v1.6.1  •  python: 3.10.13  •  torch: 2.0.1  •  xformers: N/A  •  gradio: 3.41.2  •  checkpoint: 7a4dbba12f).  

Using the GUI allows additional tools and customizations to be added into the process, such as an Image browser to see all of your recently generated work, ControlNet which gives you control over the posing of the characters in the image,  and add-ins to provide finer control of lighting and contrast to make more realistic images.  The full range of what can be done with the tools and add-ins is beyond the scope of this write-up.  There are also several ways to run image generation online, but I prefer to have my tools and processes locally to give me greater control.  More infomration on online tools is only an internet search away.

Models

Stable Diffusion provides the framework and system to generate images, but needs a trained model to actually perform the work.  There are a wide variety of models across the internet that can be used.  Civitai.com is a great place to start exploring the world of possible.  You do have to register for a free account to use Civitai, but they appear to be responsible and don’t generate spam.  Huggingface.com is a good alternative if Civitai is not your cup of tea.  

Please note that your model is the biggest variable in whether you will see Not Safe For Work (NSFW) images in the generation process.  This can be controlled with your prompts, but if you pick a model trained with porn, you’re more likely to see NSFW images.

Many of the models are geared to fantasy realms, animae and other fictional settings, but there are a fair number of high-quality models focused on creating photorealistic images.  Depending on the genre you want to create characters for, pick an appropriate model. To illustrate, here are three character images created from the same inputs, but using three different models.

Common prompt: photograph of a young woman standing before a huge dragon, Seed: 2988225084, Sample steps: 30, CFG: 7

The first model is v1-5-pruned-emaonly and is essentially the default model most tutorials tell you to install while getting set up.

The second model is Ghostmix_v2, and can provide good images for a wide range of content.

The final model is CyberRealistic_v33, and seems to do well for me when generating photorealistic content and pictures.

My go-to model currently is the last, CyberRealistic_v33. Unless I state otherwise, that is the model I’ll used for the remainder of this article.  

There are several other settings within the UI that can have a large impact on your images.  These include the number of sample steps used (30 in all these examples), the CFG Scale (I’m using 7 in this article).  You can also select your sampling method and upscaler used.  My defaults are DPM++ 2M Karras for sampling method and R-ESRGAN 4x+ for upscaler. 

Prompts

A prompt is the natural language input used to generate the image.  Generally speaking, you want to keep your prompts as simple as possible.  Depending on the model you use, the “as possible” can still result in a long prompt.  Prompt length will also affect how quickly your images are generated.  Additionally, there are both positve prompts (what you want to see) and negative prompts (things you don’t want).  For negative prompts, I have an add-on the is specific for my preferred model called CyberRealistic_negative.  I can put this in my negative prompt input box and avoid a lot of extra typing. 

 For the first examples, I kept the prompt very simple “photograph of a young woman standing before a huge dragon”, with no negative prompt.  Now I want to be more character-image specific.  

If you want to have a consistent face as you iterate on other settings, you need to ’trick’ the model by having a common descriptor in your prompt.  Some creators use a name: “photgraph of young woman[ingrid] standing under a tree”.  Others suggest using a nationally in the prompt, such as: “photograph of a young Norwegian woman standing under a tree”.  

I prefer to have a bit more control over the facial features of the character, so I like to use real people so I can have an expectation of facial features, but I always blend two people to give a unique, but consistent look.  For example, “photograph of a young woman[Joanna Krupa:Summer Glau:0.5] standing under a tree”.

Using this approach has a few of benefits for me.  Firstly, I get consitent facial feaures and structure across multipe runs and many image settings.  Secondly, since I’m making character images, it generally produces faces that are easily visible in the frame of the image.  I can also blend the mix of features by adjusting the number part of the prompt.  Using 0.5 means it will shift between the two faces 50% of the way though the image generation.  I can easily change that to 30% [:0.3] or 70% [:0.7] by adjusting the prompt. Finally, I get natural hair and eye colors without adding anything to the prompt.  I’ll show you how to override that in a moment.

Let’s see what this approach give us.

Not bad.  I like the overall pose and compostion for now, so copy the seed (4115103065) so I can focus on the details of the character and not worry about the composition changing too much.  One thing to be aware of is that a lot of the models have a bias to asian norms for the people they generate.  To help make this a little less asian, I’m going to add the Asian-Less-Neg add-in to my negative prompt.  Just this simple change in the prompt has a noticeable impact on the image.

For this character, I want her hair lighter and I want her to have blue eyes, so I  modify the prompt to: “photograph of a young woman[Joanna Krupa:Summer Glau:0.5] standing under a tree, platinum blonde hair, big blue eyes.

Notice that her dress changed colors to match her eyes, which I did not want, so I’ll tweak the prompt again.  “photograph of a young woman[Joanna Krupa:Summer Glau:0.5] standing under a tree, platinum blonde hair, big blue eyes,  wearing red dress”.

That did not change as expected, so let’s increase the strength of the prompt here.  Enclosing a term in parentheses will increase the weight of the element by 10%, so “(red)” will make the color prompt stornger.  The alternative syntax is “(red:1.1)” which I prefer because it gives me greater control.  I can put “(red:1.5)” to make the weighting 50% greater instead of trying to figure out nested parenthases.  That seems to do the trick. “photograph of a young woman[Joanna Krupa:Summer Glau:0.5] standing under a tree, platinum blonde hair, big blue eyes,  wearing (red:1.5) dress”.

I can now iterate and add details until I get close to the image I want.  I can also move back to a random seed if I want some alternative compositions to consider, or use the “extras” feature to create variations of an image.

Here are some of the variations I reviewed before selecting a favorite:

Here is my final result and the prompt that created it.

Prompt: (full body) photograph of a young woman[Joanna Krupa:Summer Glau:0.6] standing under a blossoming cherry tree, stream flowing in background, athletic build, fit, slender waist, narrow hips, platinum blonde hair, french-twist hairstyle, big blue eyes, smiling, (wearing a short (red:1.5) beaded cocktail dress with black details), (black lace gloves), rim lighting, sunset, twilight, soft focus, dof, 

Negative prompt: CyberRealistic_Negative-neg, Asian-Less-Neg, 

Steps: 30, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 1017757063, Face restoration: CodeFormer, Size: 512×512, Model hash: 7a4dbba12f, Model: cyberrealistic_v33, Variation seed: 2310841748, Variation seed strength: 0.31, Denoising strength: 0.65, Hires upscale: 2, Hires upscaler: R-ESRGAN 4x+, Version: v1.6.1

Notice that the lace gloves fell out of the image, even though I boosted the weight of the prompt slightly to include them.  If I had to have that detail, there are other ways to re-work that part of the image or reinforce the prompt even more, but that would make this post much too long.

Additional Prompt Considerations

As mentioned above, some models have been trained using porn images.  If you want to minimize generation of questionable content, you may want the add “SFW” to the begining of your prompt.  Of course, if explicit images are your thing, you can apply it in the negative prompt instead.  

You can also adjust the number of sampling steps the process uses.  Generally speaking, more steps give you images closer to your prompt, but sometimes you will reach a point of diminishing returns.  

Finally, you can change the medium you want the image created in. Here is the same basic prompt, but using a water color medium and mimicking a specific artist’s style.

Prompt: ( watercolor \(medium\), IrisCompiet:1.2), <lora:IrisCompietStyle:0.9>, painting of a young woman[Joanna Krupa:Summer Glau:0.6] standing under a blossoming cherry tree, stream flowing in background, athletic build, fit, slender waist, narrow hips, platinum blonde hair, french-twist hairstyle, big blue eyes, smiling, (wearing a short (red:1.5) beaded cocktail dress with black details),

Other add-ons

In addition to the default capabilities of Stable-Diffusion and Automatic1111, you can extend your workflow and tailor how images are generated using extensions.  The most common are LORA’s and Textual Inversions.   The negative prompts referenced above are actually Textual Inversions. The extension used to make the water color image in the style of Iris Compiet is a LORA in action.

It is also not uncommon to use a Dynamic Thresholding Fix (also called a CFG Scale Fix) to allow more dynamic range in the output images and make them look more realistic.  I use several of these on a normal basis.  For this post, here is the final image I selected and the full prompt and settings used to generate it.

Prompt: (full body) photograph of a young woman[Joanna Krupa:Summer Glau:0.6] standing under a blossoming cherry tree, stream flowing in background, athletic build, fit, slender waist, narrow hips, platinum blonde hair, french-twist hairstyle, big blue eyes, smiling, (wearing a short (red:1.5) beaded cocktail dress with black details), rim lighting, sunset, twilight, soft focus, dof, <lora:epi_noiseoffset2:0.75>, <lora:LowRA:0.4>, (low key), <lora:add_detail:1>, <lora:lora_perfecteyes_v1_from_v1_160:1>, (perfecteyes blue eyes), 

Negative prompt: CyberRealistic_Negative-neg, Asian-Less-Neg, 

Steps: 70, Sampler: DPM++ 2M Karras, CFG scale: 25.5, Seed: 1017757063, Face restoration: CodeFormer, Size: 512×512, Model hash: 7a4dbba12f, Model: cyberrealistic_v33, Variation seed: 2310841748, Variation seed strength: 0.31, Denoising strength: 0.65, Hires upscale: 2, Hires upscaler: R-ESRGAN 4x+, Lora hashes: “epi_noiseoffset2: d1131f7207d6, LowRA: 0dfc93870ba3, add_detail: 7c6bad76eb54, lora_perfecteyes_v1_from_v1_160: a20338fde571”, Dynamic thresholding enabled: True, Mimic scale: 6.5, Separate Feature Channels: True, Scaling Startpoint: MEAN, Variability Measure: AD, Interpolate Phi: 0.95, Threshold percentile: 98.3, Mimic mode: Half Cosine Up, Mimic scale minimum: 4, CFG mode: Half Cosine Up, CFG scale minimum: 3.5, TI hashes: “CyberRealistic_Negative-neg: 65f3ea567c04, Asian-Less-Neg: 22d2f003e76f”, Version: v1.6.1

Final Thoughts

This has been a quick overview of how I approach making some character images.  I don’t want to even pretend this is the only way.  I prefer photorealisit images, but could just as eaisly generate pencil drawings, water color images, and much more.  Hoepfullly this will help some other person wanting to explore image generation via AI.  Like the post and follow if you want more this type of content.

You can see additional samples of my character images at https://www.charliefoxtrotwriter.com/character-images/